From 4b99ff7fbecd2a675e68049cf731d6f25705ede5 Mon Sep 17 00:00:00 2001 From: Dhanya Maliakal Date: Thu, 3 Nov 2016 12:31:34 +0100 Subject: [PATCH] reset fpga implemented, changed receiver configuration warning prints, powerchip implemented --- slsDetectorSoftware/commonFiles/error_defs.h | 7 +- .../commonFiles/sls_detector_defs.h | 3 + .../commonFiles/sls_detector_funcs.h | 6 +- .../jungfrauDetectorServer/firmware_funcs.c | 145 ++++++++- .../jungfrauDetectorServer/firmware_funcs.h | 5 +- .../jungfrauDetectorServerv2.2.1 | Bin 125516 -> 126332 bytes .../jungfrauDetectorServer/server_funcs.c | 287 ++++++++---------- .../jungfrauDetectorServer/server_funcs.h | 2 + .../multiSlsDetector/multiSlsDetector.cpp | 35 ++- .../multiSlsDetector/multiSlsDetector.h | 11 + .../slsDetector/slsDetector.cpp | 143 ++++++--- slsDetectorSoftware/slsDetector/slsDetector.h | 12 + .../slsDetector/slsDetectorCommand.cpp | 62 +++- .../slsDetector/slsDetectorUtils.h | 9 + 14 files changed, 501 insertions(+), 226 deletions(-) diff --git a/slsDetectorSoftware/commonFiles/error_defs.h b/slsDetectorSoftware/commonFiles/error_defs.h index 2cae81994..c010f26ba 100644 --- a/slsDetectorSoftware/commonFiles/error_defs.h +++ b/slsDetectorSoftware/commonFiles/error_defs.h @@ -70,7 +70,8 @@ using namespace std; #define PROGRAMMING_ERROR 0x0000000002000000ULL #define RECEIVER_ACTIVATE 0x0000000004000000ULL #define DATA_STREAMING 0x0000000008000000ULL - +#define RESET_ERROR 0x0000000010000000ULL +#define POWER_CHIP 0x0000000020000000ULL // 0x00000000FFFFFFFFULL /** @short class returning all error messages for error mask */ class errorDefs { @@ -218,7 +219,11 @@ public: if(slsErrorMask&DATA_STREAMING) retval.append("Could not set/reset Data Streaming\n"); + if(slsErrorMask&RESET_ERROR) + retval.append("Could not reset the FPGA\n"); + if(slsErrorMask&POWER_CHIP) + retval.append("Could not power on/off/get the chip\n"); //------------------------------------------------------ length of message diff --git a/slsDetectorSoftware/commonFiles/sls_detector_defs.h b/slsDetectorSoftware/commonFiles/sls_detector_defs.h index ddc7d62c6..8e3a82689 100755 --- a/slsDetectorSoftware/commonFiles/sls_detector_defs.h +++ b/slsDetectorSoftware/commonFiles/sls_detector_defs.h @@ -25,6 +25,9 @@ /** maximum rois */ #define MAX_ROIS 100 +/** maximum unit size of program sent to detector */ +#define MAX_FPGAPROGRAMSIZE (2 * 1024 *1024) + typedef char mystring[MAX_STR_LENGTH]; typedef double mysteps[MAX_SCAN_STEPS]; diff --git a/slsDetectorSoftware/commonFiles/sls_detector_funcs.h b/slsDetectorSoftware/commonFiles/sls_detector_funcs.h index 74405a0a4..d76bbd840 100644 --- a/slsDetectorSoftware/commonFiles/sls_detector_funcs.h +++ b/slsDetectorSoftware/commonFiles/sls_detector_funcs.h @@ -106,9 +106,9 @@ enum { F_SET_NETWORK_PARAMETER, /**< set network parameters such as transmission delay, flow control */ - F_PROGRAM_FPGA /**< program FPGA */ - - + F_PROGRAM_FPGA, /**< program FPGA */ + F_RESET_FPGA, /**< reset FPGA */ + F_POWER_CHIP /**< power chip */ /* Always append functions hereafter!!! */ }; diff --git a/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.c b/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.c index 3b2394e7f..238af0281 100755 --- a/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.c +++ b/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.c @@ -7,6 +7,7 @@ #include "firmware_funcs.h" #include "mcb_funcs.h" #include "registers_m.h" +#include "gitInfoJungfrau.h" //#define VERBOSE //#define VERYVERBOSE @@ -116,7 +117,7 @@ char mtdvalue[10]; int mapCSP0(void) { - //printf("Mapping memory\n"); + printf("Mapping memory\n"); #ifndef VIRTUAL int fd; fd = open("/dev/mem", O_RDWR | O_SYNC, 0); @@ -163,6 +164,7 @@ void defineGPIOpins(){ } void resetFPGA(){ + cprintf(BLUE,"\n*** Reseting FPGA ***\n"); FPGAdontTouchFlash(); FPGATouchFlash(); } @@ -177,18 +179,143 @@ void FPGATouchFlash(){ system("echo 1 > /sys/class/gpio/gpio9/value"); } -void powerChip (int on){ - if(on){ - printf("\nPowering on the chip\n"); - bus_w(POWER_ON_REG,0x1); - } - else{ - printf("\nPowering off the chip\n"); - bus_w(POWER_ON_REG,0x0); +int powerChip (int on){ + if(on != -1){ + if(on){ + printf("\nPowering on the chip\n"); + bus_w(POWER_ON_REG,0x1); + } + else{ + printf("\nPowering off the chip\n"); + bus_w(POWER_ON_REG,0x0); + } } + + return bus_r(POWER_ON_REG); } +void initializeDetector(){ + printf("Initializing Detector\n"); + + int i; + //printf("Bus test... "); + for (i=0; i<1000000; i++) { + bus_w(SET_DELAY_LSB_REG, i*100); + bus_r(FPGA_VERSION_REG); + if (i*100!=bus_r(SET_DELAY_LSB_REG)) + cprintf(RED,"Bus Test ERROR: wrote 0x%x, read 0x%x\n",i*100,bus_r(SET_DELAY_LSB_REG)); + } + //printf("Finished\n"); + + //confirm the detector type + if (((bus_r(PCB_REV_REG) & DETECTOR_TYPE_MASK)>>DETECTOR_TYPE_OFFSET) != JUNGFRAU_MODULE_ID){ + cprintf(BG_RED,"This is not a Jungfrau Server (enum:%d)\n",myDetectorType); + exit(-1); + } + cprintf(BLUE,"\n\n********************************************************\n" + "*********************Jungfrau Server********************\n" + "********************************************************\n"); + + //print version + cprintf(BLUE,"\n" + "Firmware Version:\t 0x%x\n" + "Software Version:\t %llx\n" + //"F/w-S/w API Version:\t\t %lld\n" + //"Required Firmware Version:\t %d\n" + "Fixed Pattern:\t\t 0x%x\n" + "Board Revision:\t\t 0x%x\n" + "\n********************************************************\n", + bus_r(FPGA_VERSION_REG),(long long unsigned int)(((int64_t)SVNREV <<32) | (int64_t)SVNDATE) + //,sw_fw_apiversion, REQUIRED_FIRMWARE_VERSION + ,bus_r(FIX_PATT_REG),(bus_r(PCB_REV_REG)&BOARD_REVISION_MASK) + ); + + + printf("Resetting PLL\n"); + resetPLL(); + bus_w16(CONTROL_REG, SYNC_RESET); + bus_w16(CONTROL_REG, 0); + bus_w16(CONTROL_REG, GB10_RESET_BIT); + bus_w16(CONTROL_REG, 0); + +#ifdef MCB_FUNCS + initDetector(); +#endif + /*some registers set, which is in common with jungfrau, please check */ + prepareADC(); + /*some registers set, which is in common with jungfrau, please check */ + initDac(0); initDac(8); //initializes the two dacs + + + //set dacs + printf("Setting Default Dac values\n"); + enum dacNames{VB_COMP,VDD_PROT,VIN_COM,VREF_PRECH,VB_PIXBUF,VB_DS,VREF_DS,VREF_COMP}; + int retval = -1; + int dacvalues[8][2]={ + {VB_COMP, 1220}, + {VDD_PROT, 3000}, + {VIN_COM, 1053}, + {VREF_PRECH,1450}, + {VB_PIXBUF, 750}, + {VB_DS, 1000}, + {VREF_DS, 480}, + {VREF_COMP, 420}, + }; + for(i=0;i<8;++i){ + retval=setDac(dacvalues[i][0], dacvalues[i][1]); + if(retval!=dacvalues[i][1]) + printf("Error: Setting dac %d failed, wrote %d, read %d\n",dacvalues[i][0],dacvalues[i][1],retval); + } + + + //done from config file + //printf("\nPowering on the chip\n"); + //bus_w(POWER_ON_REG,0x1); + + /* Only once */ + bus_w(CONFGAIN_REG,0x0); + + printf("Resetting ADC\n"); + writeADC(ADCREG1,0x3); writeADC(ADCREG1,0x0); + writeADC(ADCREG2,0x40); + writeADC(ADCREG3,0xf); + writeADC(ADCREG4,0x3f); + printf("Configuring Vrefs\n"); + writeADC(ADCREG_VREFS,0x2); + printf("Setting ADC Inversion\n");// (by trial and error) + bus_w(ADC_INVERSION_REG,0x453b2a9c); + + adcPipeline(HALFSPEED_ADC_PIPELINE); + dbitPipeline(HALFSPEED_DBIT_PIPELINE); + adcPhase(HALFSPEED_ADC_PHASE); //set adc_clock_phase in unit of 1/(52) clock period (by trial and error) + + printf("Reset mem machine fifos\n"); + bus_w(MEM_MACHINE_FIFOS_REG,0x4000); + bus_w(MEM_MACHINE_FIFOS_REG,0x0); + printf("Reset run control\n"); + bus_w(MEM_MACHINE_FIFOS_REG,0x0400); + bus_w(MEM_MACHINE_FIFOS_REG,0x0); + initSpeedConfGain(HALFSPEED_CONF); + setSettings(DYNAMICGAIN,-1); + + + + //Initialization of acquistion parameters + setFrames(1*1000*1000); + setTrains(-1); + setExposureTime(10*1000); + setPeriod(2*1000*1000); + setDelay(0); + setGates(0); + + + setTiming(GET_EXTERNAL_COMMUNICATION_MODE); + setMaster(GET_MASTER); + setSynchronization(GET_SYNCHRONIZATION_MODE); + +} + u_int16_t bus_r16(u_int32_t offset){ volatile u_int16_t *ptr1; diff --git a/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.h b/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.h index c1c7a362f..2dc493559 100755 --- a/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.h +++ b/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.h @@ -24,7 +24,10 @@ int mapCSP0(void); void defineGPIOpins(); void resetFPGA(); -void powerChip (int on); +void FPGAdontTouchFlash(); +void FPGATouchFlash(); +int powerChip (int on); +void initializeDetector(); u_int16_t bus_r16(u_int32_t offset); u_int16_t bus_w16(u_int32_t offset, u_int16_t data);//aldos function diff --git a/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerv2.2.1 b/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerv2.2.1 index b79b7afa751da82e04a5d93d7c9d87bdc964ff92..975475feb1ffbbde80e27ae712f54198bac313a3 100755 GIT binary patch delta 53308 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 delta 52741 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 ?@T(2|6^MrZGur*v`(pn$Fa0Vds zPqmr1_$&;yD^ys$%|%a$riIQ}I$voI@liyjcUbYL>7X`)u2c(1|5V9Lm5Kx;!$Vh1 z$>`9!5;G1@0%MHc4Fg2Y9BT-Ue%`n4Nb+^W4`VW-6pX-V|4yD*J&Y;UhPd_-tU4r> z!IJCR=kN??GIY81z4_dFM@lk-w}0w2{JMHaK{6AgTUQ&*ud8*eO2)L`R)g;_*PL)A zGq`!X8pS!-l>`tMRiVbX%q!yH7V$f<18@s^8zx|w zx8ali+v*(`%}jE3PgEk!A!donyNo~8u{}_AaG6WGD$ATYPK{)eVyu+wcj&3NH%4#FhED;7V9Gz6%0%eA zeMwGbVkTMN`T2CpcQD#wnY5sO(P`74oTm@!?dvmJv-vT~(=ibby%cUiZvIkoRHrg? z(v|*5eR;@SQt*vf7d-(5{6QOXr-U8xqnOOpJL{Ge&{p3QTg5x?ceHt8$0#OI6QL~b z>ZRS$I-0S<_GI(+eUe?HO0Pjmc1dWy?2_2`(FthB5Zmjg*JK-dMPquvGSHe7pRPSc za1-e4-xv{u;MkhZ%+^(*MpeDzS~@c)q-7sG^nLh5(mpup`y7R17*j+w%Bw|+nrPa> zPNa9%JGPHuGBRrG>Dn5^*NT^#qgeX3h&<3Hyz@>|1m%Qe8>HItXgNN@aeE9C9lsHj zHr98(O|c}Z4T#64hNUK@=7J|Z(yOFbdAN?Q;^>a0*$3eBazT$1lJ+~)M+raQHhhy^uX0oouq32s1j!P4mG{gfDKM`hO=4f!}-XBZq0x?cXQH-+zd?<&B?cp2UnW{+CZMIbyPpXY)=eFJRBco(fnNhdMKO%ZFo?r=9dAcz*0RNh#PPLP>SG~ zl*hzRO03;-G>}hJ;g7@=OsvI6aB4$yo-{wgPXN6MwHmR0FSrnSNChE;=1fb4i-6MH zT8Ar-DYO*UHvb%sdF_DI%2^qI`Lye`KX-NI;;)QP;Y(m9OKK;YyM&K#+YJHH_q}ec zVf1~XY0h4}m0kjhCABAVA7!E#x!Wa^m4u^e3X{o}fl66z0QM@+AofhH1 zpRGM{a|(m^10^@)gf*X8qR|%|$483zg5!?!)0pES`}Y~mjYs0liK&5*_K987nIjA` z8;{&P;&GeAOvlU_ObdJI?T2CaHTQSvzRCS$J0JgCPE zDoSMxA<=qM9`8bqOU%(BRfkkveE?$n5!+wyNPmLa@t^de;|ZoxJY_*+Qlebu8YE%n9?8%=F&6hJAs2!#+oql^HiEej1)Wb$R#OnEGA99}0ZC?-PHp zGAkK}c@1N6OfF)KC#u#kt&F2=4P$f^KF<_5u2mqm|9Ph5L~#+bN)uHQPRQ;4glHoO z{%RN@;Rw+P@ewDk7c(8YsEs2C*@56hIE2uIa2lawgyZ^BW_@b-NJ5ej(h$ZYVmPt4l=&(k?#)SrBP43Ne<=3m%>?v#g{uv<$BnNv!LWf>uH%b}zzPK>iLm4<|ahY0zi zTR4LBNrVp(P9vN@bmGd(OqkAQ{0i%zH=G9C=M9GddS@le0P$JNi!Rxi}9cNM0>&$K9`1e6(Xtpze!KWc$M?&;lG@F@Oc&Y1E z?c2RbH1eFN5UpcKMGxgB+RV5E_i6}?bt`t7xa$P?}C4AAIEn{ z2UwnB$S%suK;3SL`O;I4@%2D!p6w{AXA*6_+X?B7$NG95!NqX1(7lL5_u;{me) z3jk*T!U@zb1Y8AJ0k|1(DF{cga6fQJB^0Gk2N0-gtK18fJp4)~px1f~!Yn5wmr zKr|ePh6A$!Cjo+iKrj$E6L1#b62Rqv>j5hPcL44J+y{6N@Fd{-fM_TX4Fz5S>;U`@ z@TQgo1z{S50LB2u0j2_`15N_Wvmr7IkvV|N0m}g^0XGBg0(=7yJqkjPg5C%G5b!+U zMZgZguK;fX-qw;nA%ye^1B?Sq089rQ2bc#q6>tt<5nwssYQW8aHi)jz8;HCKcnI(a z;D>-80bT_B0`M!qZwyd*EtB3rnDizsGx``|MmK1gGz($UauLE{!nf`Tz>3;+ebo!qHya?E?Wg?mh6Y-IjiCjXM$O=F^AQ*@( zBTVdiz|DZ$v^FLd4aZ(Zh6nIFEfZ%UOx#q!nSiqaPXmI%xHiBJEi)vEFheo`^8lv< zt_HMgnfM&S#1{b02DAcJ0agQ|$MIiknH11VnFY8OuoCb?z>jQ*e22(wEi+;qVMdGx z1i=wNFlQ6SoCkOa5Irwd&w;m8W5cdT{9|X~d0j2_4 z03o3vmmzWjk?R4|0mlJW0It(ALlX%z6bz2K0ZC~fu@o|jNlS&OWXpLGDg6S55>88Do^mkg)3)8q4rg1M! z&t90GTFiSb=Dil@lG-#tOhYZEA^zAS(N+R}1b78|mW)XvWK0UusYs^-x&V)9@iqqB zRS+_i0G0w`6)@NVF9Wt|35yP~=n#9GkWh`5;3ZTNhWcS1z#Cc;K8}#^@i1KBFd*Tu z9}(GvL`>3>$O1wlXK0BLJvXA~18%`9B3cra4hTaOeIBdIMJ*W&{K3GFgGq^FwPYyh z39@tCB1N*dO0vMhEh9^`5?$i|b_x=M$Ri-~NH87=#$i1PtS5;9UJUSJA%R#( zARa>zkD(aW3`w+TNg^bX2ua+x6<+my=wZ@K>>y@oNiql~gJ24l`;=rY88MxZ5i=nn zR7gdIw2P3)7mxrL%>bj81bBu?=;?U$G#fodIveSU;pnMROL9`-7^I`e$I;`H=hKo*ANg00fCVHfc1dq0WU%l80)?mYuJ4PyHD5) zP_j!l4`(5%a6sUP13v<5Q^XOZXCaNnGSUW)Bf)VV#xxIO zYP3M9mki;w{X%9sZ@6%Y&!07FqoMj3uyUIuK#tSH5-Cd{Hwv?3 z6lTY$4#2OpWHcl)8WI@|#z%wk(aQm0%149o(O^718ur8lSd96fUV;cJrlaB*G&BYc zjk%5KrNK0V4rD+FG9bbXh%ndtd@|mdO%2OEF?A7444MPR1U+m8t^3G z`+&Cy$s}5mi4J9=Ll1m`{4bG?!TisRLu3vLiU7fBCOFN6s52qz%qGBQEqO4EkOw0G zQvuTfCjsUG0`EcKJqWx9Dc(1L*R^DP3{E0Icl<`cD!^L6-LQ}eu#icB=K(JQUd8;M z0Hw2F3@sSLED*{9q3nY&B!^%~PQj3zfgypYb0F%RTQDR924yl}ftE~~PROL0fMtNI zwB+HN<=mz0}W3@!_(db+zW{5GR*~uF`R}moCb!bfuU(o z(rHlAY3+bl0j~porzH>snXUy40Sp6-1~j2O7v+<+|L3J6G7b<8%tHf3+X*S!p(XQK zLgt49rU0gDNijrQ4ACz5e-+(-P*>NT|MBy2?pVSaMMH_T6pd1&t`cgH7;7yd)=)LX zAr9j>j>Edf5JQNglv=|Gv3@OesT%5{vBot7DH4_vL_!TJL1NGlV~ug~M_t!(9oKan z$8j9Tb)4_RKTe+a=li_hulM_$`{CYW>&Dkcpp?BPWv{KqGNjyVlzZ(0Uc!6$APUP| zzs&W^*jdKTvW2)f3a_sW;q~%T2U;9x!*h7iiO7jKoQ_#&*u8Gp70w8uFdN-i=)N~L z`kcHe3d{2>SICdTn;d?V!*7bPNQ6a-uSoH|l^w!cv!YO(8ba~7D7-x|gty~echmTP z^L7+g@^B>&SEk_TD16u-!iN{4P8cMxGnRh7j&JtXP?7YLy zJN4KYg|bn`f0^O2c4r7{cSoUufeHpHX5nlkbp@#_+*skpcUAejk$owtkdlh)c++wB zzq>mM>vn{&ZdVk3TNT1@w?tvRz}5@wwJFkM&XY-_@fT0NncI+KkE38I{xDUJQRhRGa=NR zvwzh7@hEIv=T*lB+=|m9eIT-b+aAKd?NqeO6zy{Ro%Xxz zi}XX0e%Ou&PzpYjg4%(KHy+b5!}zbIKrIDoS7Iq{#7$U_jmWWDj(ub*{U{Zu;&ha% zkEE($c?b=~cnZ&;QLr~eVQ(p}!7F$z3XK$Qq;Mm9jqH7#6vD@kp8p?jvQdrq@nIC2 zMA9UZR#n@oYFjICeH8X7zI_pvVMP==uX@XPJqib-5Dvzn>khi^@VyWYKZrt?4!YRy zlBzDL>YnV?XeQ3X`B6AhX#5{3vaunABO9ZzXHf`y3Q&&s$nl=_ScxRwL*hM6*doF# zkG^85;4dZO=z+KpYP1u9IBAg|{*?18zN1=tpEhKKc?2EA-31kHQxdL--;c7hypZj$R1i=%pwe zBiS*M9ovm{coI(|1&>ki*hBB`2SnjGg^p9`tEC})Rfy|wLlnMl3gPRPDEv(-{w5Wt z>U|(+H2zPC@RSI@tqbAX2JFG!DD)5Tns*?Qu%Cqer|?V^&Whx$NX~NLEC{I}1wvD7FiM4q?vyqyB=6!>(M zs!zq~n1v14ggX3Gho4@<8>&50?Qu90bFcuHVk@@e2|T5U+4+o}&lcb!#aU$hcapNR z5~~y;j}P(FdK_;C9cJFYQ_Gy_P^bP)oQ^!a@IU@_5dED45`~l zz2E)&-M`;```x$yI^Gm$dA>*&+UUlkBGTcfI{dU958z$AFM>P~ap8<3N(}zu$@dPP8X+U<9ti4R{l8 zb6_C{7UM?T#DUQq7>f*dFx+tiZ*hntpK;`~4(vp!`Alj$hjTC)Io$ckVb$NM`VZ^( zaI^7$tc9m-JQmq8k$okHU&-NDs{X45B2W|GN^n1q`+0o!l1Q!?W>R!sivF5uW}BwN zK{`xecm%^KhIOZ5-Q_-x^mF9%I?sRxY{hmwjs3>|=T~f8^Kb|r4v~k^I1i(VQRvAC zp=TR0K z;haFu3FMq=Kd0KyPovljl+yE3`UM5czaZf$k(?4qKZ*KD^hLi2E|_|Un|hOx5=SZV zWul0N<4nxK0$hq)aI5Rax^4m%<4Pp;QBohhhY!$oM_uh zvC(O#-TR$;zjN<*?)}ca-?{g@hasFH!Wq7t;ma9foEg3C!m-#7%L(33@P5Mf6ZYIx zr8FILa4ssnb4u^L_|J>~d! zMsC5azN?M&*=l5~152?GeY_dzBhN@3k318_QZ|KHN_7+)l@Ma1d`%jajHyvevmQAxhXZq3u)Iwq6GW00#qxZX%G2SiDIxai=qQ%3AjA?D z;SyYiq)(`cVoxye#CD&jDD~_*`yzQ_r~NhdH`uSXzuW#=`x||8E%VK_0&k$2`QZw$ zrb}>*>FI}Sz4MamT)BT`qjz1KynHY8^1aAQ^b201U-HIipf^VGQP{9Ogbh2RQ0aW7 z^OY^w<_|T;KXSauY|vyjXgY)EqVVtW{vpa>%*8xhkH*lypTJXo?Dv?ST6+CGv&r8x z)p!WI{fJ)XNAz-k*D!dH!GlJ@L8G9n&fhf+Xu9b#-E=SUL|KNe>vr7{jvV30kzVXG z-HEhUq$g(>?AcMcP!hrg)8XGw88v6{(d)^--!N<%44bAX{O80F{xjWhN-~^AhUV+xKhWJ*YTzZIMBj@Y13Vo6@{PM|GE7amwT;Q9EIPRj(%r4`rU4-fhDU?=vW~o-*%d**8zTn~Qngm0k9(?5Y+%&$rQYm)!^B3_QdYL2bu*y>uW_W~!y3!Kqdh84#DZy5RwLoe_2K6JO2 zadQ37a{bS#IL_}Gp10L0KEo%WC5jDA3$dXYzO8QYZB-E_6gj>kihbX=((m6hA9R=x zI-}T=zO6nPMX{&yL+mM^Ovh~X&DHg(BSI|IypURtjmH1WNg?*~2nGzd@2mdrU&osa zRWh{0jjDRgdQ|me44YJ=AayJ5#NEC=8+JohqG}(a+J{`gE6AaQz#hlH-;P~qm?zb; z+sK|k#!NT<$IP;k%b@X`YCNYJcBxCb#GwbxhS;l2tdGvF(7Qf3rOTN+|% zMR*eX@e*E(V$bA;*faC78BJ`@P~;hkq!096eh}(7or3AzSkCZI82rgp2J#p%k)#>d zX>0Kinn==a<9&uQ88Rh5vl5+8pTU6r^hOk6`YAleUNU>*Fbi|c17^TyA4ai^xDd-o zv^GN^nF7h29%4%}vusRozy$Q8t0DFy9c9=1%-tNtUMvZ*7gtBInH-wACW_5Y39;EG zra3yElO4t8%?z=5^GsZki7O$Bjo%ew<4Kz*m3dOI*maAuw>>!N**ImO#USw(gACS& z>2r}j3y_MLg}4c+omqoBw$1%pY(#mIQIceoB<;dlUn}POTCu>_2AqMp=9ygc%qug^ zTRAun=cDQ471PJ73qyEyG1`CC{>EY6^(EmbOpU_3qeFOiET&_IAa;Zh+vNrIdM~Ie z{d8V(z{VkOnmO_sM_y~hX6(c+Jb|aYKwjzvav^f`b&kI7y4PLz`cXWN=9|~eH?LpE zn;hWiMvhkHhfuW;Yj8&t{=lI>aOe+B*y5-2=C}|x55hL=z&<<~g)Jj2V@tuwn28m* z9!-E-On~osyuau1{+{{lJ@eUnYj7=!@I4W}cMZ*Z)$CWZznmh=DN@zNksc1r0C>!zRjU)SLx=rx71Uyl$00C$=h=Fww%4O+>OONz3#@FQFwE82yd1l z$KK>vQ3eB3krG9eC?aVQNsF4X6??G{FXCn7z*`)6D+x#75?qFBa4lAQHoaA2qsf65 z?8c*b8L#3!e85x1SFHGo7hwUe#dWA=iq%YUBQ|3X_96v}De(4Kfla^}n2iOv6iaap zR(UqPy~Rd7Hlm_?ThYCJ8v9WMD@0I5nJUUu>8MIaf5?=wY1oe!q;7-MZIr6TQndtk zVXag}QWb~p-{Sr)ck#a3P|WWYV!5h)Pt|_Z>hazlg*wGjr&#I~U0o*T<3e1CrML;J zkt1~+sUvwE$?LA*HE%a{xJQS3QgNJzCnZ`a(Q+RjM&Xmh5Iz}>4cO$_^a%r>Fz^Y< zKOy-6(i|X7H^;g;)_oPP`@>N!^r(fNDil`Fb-amE)FVY7T@=7&_b+h&BCNq3Q8+Xp zghK-{8Atg;l>?u1;PW(mwC3+4hCX7brJaWdI5M3hSy+ix-pj^&FFV*nlA$(++D7A8 z9URg@w~l+<-%A0*t1i{P)O{p%AKk_Kj?Z@7qi3i`$IzR2FT{pLe!(UA1?SUQ>-%s8MX*b^<(aMW-a&3D)w~t%t?rMe3|3R z@d{oyQ{(t+etJ4T!TAhN<%|?F^cl0WM@WW;WJYK&?wOV^o0hM77J2%nZSf2$ z@C;gtNAWm1|BUnLqdkMhx^KJtc47v4wq?$9f4=>h_C1rPxPFT3r>w(`QEc$t5F6~# zGvD#~j?ed7b=dq{Ho6@+il?!EThV`bEf(D3Ee;)Ek?1f?LKPjSqT@1g8s^|!T!@QNhjBWLTZ`*(3vR_)tj9L&K#s(5B+k%{ zGj!wBU!3}j)8AwIdrW_iC3!A9HrB=joQ5+n7xQolF2hn>gBx)Z?!sDZ#dg%uV>){5 z9A3nmc-tCLg&ePtLwJyolmO6yJ^q@Hn2p zi+CAt<6Ub-2U;r{k0USz({M6o<1Ea_g}5AxaV@UHYR`p#sIgJ+KqDT&LwEvD;bpvP zwcA6v8ep|roYiWBFa<|rCQic=T#XbOM4>^a(a?OH^pBH%@SqR|C*TS!!QEJg$2}JY zi)cs`!jL$ef!S!R4>8t<+`>CiNDx_q$P#v8E%xC_yo>j(^->c<)x^+~c-qRQU}aN; zBp;TB>u>`e!fw2VH=^)FpXb683?+&zQDljeF%#F~I`o`K^qffKNFqm)rup?W14W!9 z;v~nD9Dg#!%Baz(Sf5m^Pg3GZN(`TBMbva$kCmu6hbzwE7xA){QROw3M(wb194YaG zJ9y6$DLEV=ha(!W$%?09E1p&&>5@s8?D}Na|0vx`rwnYu7CeU+t!kr43Pn;b;T0>P z60C$uL;;KxfEhZBqImgJ@s_;}w*0Lf4_F}R#Aqi*GdP;TF_alY89(vE7!LWHBlw#m zq;_DZB~=vrF~xpNu^&@x>>x{~5^yON;wG%dR%}NOjpfkO`h9w^@&7c#Pc!`V3M@f} zpJsU63`?xCu>#j42gh-690TJR7*F!?yd6Im=b;>rm*epqAJ6ge*YTz$Si>#BO2%Bw z!_`=Z>`gde{7<-IL6xl5P3bn`{J`67K6)?zRAS&CI-Db@~4uY#pl5$brdjwhGm8r1P*9Zxo_CmYt! za;9688FQ}0hF5+cN zv)rHU{_G{V3~R9-*~w<-#qvR3ZY0J3#Y<9A{t`nkF_g33;;%})hYu_Q z6VWe4^vf1(!$a7Oa{fy>|K%;bW9_Gu%$Abbb8#MS!fF)2Yyr%n&>RZQ*?=37y*cd7 zIfoaG|2aCGqryj(snmp@HVt%-^(O_5DjOp^D)Y(--~+y0Bm zYGah#Pm}u@ax68!keb=MNM1|1E0nutIUWb|IhZE}c~X$C!+iaHFN z&mdhk=@=fu@K6^Fb-_>(4Hc39o2HQ1Ou{83Tt-5Mo@8i54GDKp&~+)U8+Fq|{(?X#7ufW7HJ^kFDW(>Fsur>aQ7nOCDHIz`F?O@r&AyKhDK?y9$rRg3vE39a zGyZ2+kgS_zN4@P3$txV1H`vO=VWcY~o%4BBxCPyq=f+pAx$cJRl3h0nH(@n)U?-lz zbEH;F-%I20Fb*eilmkEIKt3h%DUn~!a6ZGia+WJ+uOu-%0w-f8-oiUN&ed@qF2`cj zL7oos)J&e5d3CJUG81qn=18f?9~b%Kb8()ZT4{cAO_pK~4dIY~8x;K8pirK$$WN#O zxz^!O9S+@!+x;}!;+N4@xfgMwh?C~a{Q|k?z>^#pPU7Jt{sF~)K(P^(YN5&x6UUPs z|B(oPB*GL9q;McbN>ikCiD_sUlkA zhee+s7AF-`wPLDKOe7pf!f`dY1MlGj#kE9nDbDdd*sI7yJVC@01TsM&|0reuC}k5l zG?7D-@;s*VjsHmuOk&^}(mz9be|80bc7>lD@;L2Qj0{X>U^2%hbL`oEPsIz0vq5n- z$!($B7AeLY#W)vFW540-{PWJwsQ0jG^h|lEI0q=w0$i#{6BKEAq74qbz=7-=s`Qre zEr&14;mml|IvDeDp{iA6zffeqIENQiZ?WQCi6`;2B5qT}9cIYL3>l}mq%L3T@*A-^ z3I&-V6ih?IyTI@+;7EA^PYUF;Ku-Uu)S}WgC|Ca^S4$>(WtWZ|Si*to1>SHi@`63l z3-;kwsp;TD9egOVT9MUqyq4p&YNA$6)UsR4ZmrbSO5L6{URJENU}?4mOSyQ#_;0vm zm5Bp;9oVa*y*k?4jfP_rgG~&!-t}(azHb`CebY$Bbj(1J>=Vg8j_u>vzNJ{`yS-F( zO4Y$+-#SKN22Mrx4zhP}5f)&f@qbY6x(4|Ol7Nb)OVM;G$}UCO#i1?^b&$_#p?nXD1dk*@m>n=t-$qo0#D&hylwSMx#DT$Kw~9VSq2j< zgNbkyrs8TW!|k{eui!PxM3jlcc{m?eUvaFtR6 zC^ZlT)>VbA*pA2X1iG&4s`1|?S6y=TImtdJS+|^Z%USny%)(hH72P827GXDo-3)ef zsGCFG9O~v!cMtaZUZs|fsHG!PcSP!rP~Zp!j+9{q)?*_Y-bcEP|08E?oI^P|A}2>U zbc92D+U58F)?z*8Vx9#>>nteRfSa%y>#)HaGLrU?bk8!^Etk^8Qo021;(e)GB6Z8K z7*}FHmS2#oQn^}#J8&10s+Cl&B5D;;>jk`oq;9~Huryh;paptCrUX{%863Wl`hf>w51vc zN*OO@yp-M2N6xWb%F)tC4peDdw5{59ZKt+dtJ4~^Capzl(>PMfkrz=}8;? z+6C>Bc163U-Oz4n_u^t}9>m4o30kDZX@j%`EyFqI-$~SlYsuOuEma$*P1MrkVrBER z`Pu?)kya2FtJF{By}0sNCF8$m{P&Fip7BbZSL(b{=aqNjVw>Hxd9KFDW=1yaV6zT3 z>uj?QHtS&XbZw@Vp=D`0-#k^z(R8-COsmkAYDHR!wq2_#_n$4=R&9m0UMtjAYn9p} zZKu|zb!q)tpLS9^tu<&JTCdimwP>AMkG5N@i;LAiYObqyzTWwI9oMs2?|fbPeE%uX z3bh5=QcXv7I^GksN9WvJ=f*lt)ak5F2X&0qUDIx9ceH!j1MLRG7vf@nj?*$UcK%$Z kapKP>HP<$b(sH!IxL8Uia!0RR91 diff --git a/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.c b/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.c index 2abaac10e..c09605f00 100755 --- a/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.c +++ b/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.c @@ -55,147 +55,25 @@ int adcvpp=0x4; int init_detector(int b) { - if(b){ defineGPIOpins(); resetFPGA(); usleep(250*1000); } - int i; if (mapCSP0()==FAIL) { printf("Could not map memory\n"); exit(1); } - //------control server ------- - if (b) { - //printf("Bus test... "); - for (i=0; i<1000000; i++) { - bus_w(SET_DELAY_LSB_REG, i*100); - bus_r(FPGA_VERSION_REG); - if (i*100!=bus_r(SET_DELAY_LSB_REG)) - cprintf(RED,"Bus Test ERROR: wrote 0x%x, read 0x%x\n",i*100,bus_r(SET_DELAY_LSB_REG)); - } - //printf("Finished\n"); - - //confirm the detector type - if (((bus_r(PCB_REV_REG) & DETECTOR_TYPE_MASK)>>DETECTOR_TYPE_OFFSET) != JUNGFRAU_MODULE_ID){ - cprintf(BG_RED,"This is not a Jungfrau Server (enum:%d)\n",myDetectorType); - exit(-1); - } - cprintf(BLUE,"\n\n********************************************************\n" - "*********************Jungfrau Server********************\n" - "********************************************************\n"); - - //print version - cprintf(BLUE,"\n" - "Firmware Version:\t 0x%x\n" - "Software Version:\t %llx\n" - //"F/w-S/w API Version:\t\t %lld\n" - //"Required Firmware Version:\t %d\n" - "Fixed Pattern:\t\t 0x%x\n" - "Board Revision:\t\t 0x%x\n" - "\n********************************************************\n", - bus_r(FPGA_VERSION_REG),(long long unsigned int)(((int64_t)SVNREV <<32) | (int64_t)SVNDATE) - //,sw_fw_apiversion, REQUIRED_FIRMWARE_VERSION - ,bus_r(FIX_PATT_REG),(bus_r(PCB_REV_REG)&BOARD_REVISION_MASK) - ); - - - printf("Resetting PLL\n"); - resetPLL(); - bus_w16(CONTROL_REG, SYNC_RESET); - bus_w16(CONTROL_REG, 0); - bus_w16(CONTROL_REG, GB10_RESET_BIT); - bus_w16(CONTROL_REG, 0); - -#ifdef MCB_FUNCS - initDetector(); -#endif - printf("Initializing Detector\n"); - /*some registers set, which is in common with jungfrau, please check */ - prepareADC(); - /*some registers set, which is in common with jungfrau, please check */ - initDac(0); initDac(8); //initializes the two dacs - - - //set dacs - printf("Setting Default Dac values\n"); - enum dacNames{VB_COMP,VDD_PROT,VIN_COM,VREF_PRECH,VB_PIXBUF,VB_DS,VREF_DS,VREF_COMP}; - int retval = -1; - int dacvalues[8][2]={ - {VB_COMP, 1220}, - {VDD_PROT, 3000}, - {VIN_COM, 1053}, - {VREF_PRECH,1450}, - {VB_PIXBUF, 750}, - {VB_DS, 1000}, - {VREF_DS, 480}, - {VREF_COMP, 420}, - }; - for(i=0;i<8;++i){ - retval=setDac(dacvalues[i][0], dacvalues[i][1]); - if(retval!=dacvalues[i][1]) - printf("Error: Setting dac %d failed, wrote %d, read %d\n",dacvalues[i][0],dacvalues[i][1],retval); - } - - - printf("\nPowering on the chip\n"); - bus_w(POWER_ON_REG,0x1); - - /* Only once */ - bus_w(CONFGAIN_REG,0x0); - - printf("Resetting ADC\n"); - writeADC(ADCREG1,0x3); writeADC(ADCREG1,0x0); - writeADC(ADCREG2,0x40); - writeADC(ADCREG3,0xf); - writeADC(ADCREG4,0x3f); - printf("Configuring Vrefs\n"); - writeADC(ADCREG_VREFS,0x2); - printf("Setting ADC Inversion\n");// (by trial and error) - bus_w(ADC_INVERSION_REG,0x453b2a9c); - - adcPipeline(HALFSPEED_ADC_PIPELINE); - dbitPipeline(HALFSPEED_DBIT_PIPELINE); - adcPhase(HALFSPEED_ADC_PHASE); //set adc_clock_phase in unit of 1/(52) clock period (by trial and error) - - printf("Reset mem machine fifos\n"); - bus_w(MEM_MACHINE_FIFOS_REG,0x4000); - bus_w(MEM_MACHINE_FIFOS_REG,0x0); - printf("Reset run control\n"); - bus_w(MEM_MACHINE_FIFOS_REG,0x0400); - bus_w(MEM_MACHINE_FIFOS_REG,0x0); - initSpeedConfGain(HALFSPEED_CONF); - setSettings(DYNAMICGAIN,-1); - - - - //Initialization of acquistion parameters - setFrames(1*1000*1000); - setTrains(-1); - setExposureTime(10*1000); - setPeriod(2*1000*1000); - setDelay(0); - setGates(0); - - - setTiming(GET_EXTERNAL_COMMUNICATION_MODE); - setMaster(GET_MASTER); - setSynchronization(GET_SYNCHRONIZATION_MODE); - } - //------ end of control server ------ - + if (b) + initializeDetector(); //common for both control and stop server strcpy(mess,"dummy message"); strcpy(lastClientIP,"none"); strcpy(thisClientIP,"none1"); lockStatus=0; - - - return OK; } @@ -287,6 +165,9 @@ int function_table() { flist[F_SET_CTB_PATTERN]=&set_ctb_pattern; flist[F_WRITE_ADC_REG]=&write_adc_register; flist[F_PROGRAM_FPGA]=&program_fpga; + flist[F_RESET_FPGA]=&reset_fpga; + flist[F_POWER_CHIP]=&power_chip; + return OK; } @@ -3154,15 +3035,13 @@ int write_adc_register(int file_des) { int program_fpga(int file_des) { int ret=OK; int n; - const size_t maxprogramsize = 2 * 1024 *1024; - size_t unitprogramsize = 0; - char* fpgasrc = (char*)malloc(maxprogramsize); + sprintf(mess,"Program FPGA unsuccessful\n"); + char* fpgasrc = NULL; + FILE* fp = NULL; size_t filesize = 0; + size_t unitprogramsize = 0; size_t totalsize = 0; - FILE* fp = NULL; - - sprintf(mess,"Program FPGA\n"); //filesize n = receiveDataOnly(file_des,&filesize,sizeof(filesize)); @@ -3175,33 +3054,48 @@ int program_fpga(int file_des) { printf("\n\n Total size is:%d\n",totalsize); #endif + //lock + if (ret==OK && differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + filesize = 0; + } + //opening file pointer to flash and telling FPGA to not touch flash - if(startWritingFPGAprogram(&fp) != OK){ + if(ret == OK && startWritingFPGAprogram(&fp) != OK){ sprintf(mess,"Could not write to flash. Error at startup.\n"); cprintf(RED,"%s",mess); ret=FAIL; filesize = 0; } + + //---------------- first ret ---------------- n = sendDataOnly(file_des,&ret,sizeof(ret)); if (ret==FAIL) n += sendDataOnly(file_des,mess,sizeof(mess)); + //---------------- first ret ---------------- //erasing flash - if(ret != FAIL) + if(ret != FAIL){ eraseFlash(); + fpgasrc = (char*)malloc(MAX_FPGAPROGRAMSIZE); + } + //writing to flash part by part - while(filesize){ + while(ret != FAIL && filesize){ - unitprogramsize = maxprogramsize; //2mb + unitprogramsize = MAX_FPGAPROGRAMSIZE; //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) { @@ -3210,42 +3104,37 @@ int program_fpga(int file_des) { } - 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(!(unitprogramsize - filesize)){ + fpgasrc[unitprogramsize]='\0'; + filesize-=unitprogramsize; + unitprogramsize++; + }else + filesize-=unitprogramsize; + + ret = writeFPGAProgram(fpgasrc,unitprogramsize,fp); } - if(ret!=FAIL){ - if (differentClients) - ret=FORCE_UPDATE; - } - /* send answer */ - /* send OK/failed */ + //---------------- middle rets ---------------- 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; + } + //---------------- middle rets ---------------- + + + if(ret != FAIL){ + //print progress + printf("Writing to Flash:%d%%\r",(int) (((double)(totalsize-filesize)/totalsize)*100) ); + fflush(stdout); } - //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 @@ -3255,13 +3144,21 @@ int program_fpga(int file_des) { ret=FAIL; } + if(ret!=FAIL){ + ret=FORCE_UPDATE; + } + + + //---------------- last ret ---------------- n = sendDataOnly(file_des,&ret,sizeof(ret)); if (ret==FAIL) n += sendDataOnly(file_des,mess,sizeof(mess)); + //---------------- last ret ---------------- //free resources - free(fpgasrc); + if(fpgasrc != NULL) + free(fpgasrc); if(fp!=NULL) fclose(fp); #ifdef VERY_VERBOSE @@ -3270,3 +3167,73 @@ int program_fpga(int file_des) { /*return ok/fail*/ return ret; } + + + +int reset_fpga(int file_des) { + int ret=OK; + int n; + sprintf(mess,"Reset FPGA unsuccessful\n"); + + resetFPGA(); + usleep(250*1000); + initializeDetector(); + + ret = FORCE_UPDATE; + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + + /*return ok/fail*/ + return ret; +} + + + +int power_chip(int file_des) { + + int retval=-1; + int ret=OK; + int arg=-1; + int n; + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + +#ifdef VERBOSE + printf("Power chip to %d\n", arg); +#endif + + if (differentClients==1 && lockStatus==1 && arg!=-1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=powerChip(arg); +#ifdef VERBOSE + printf("Chip powered: %d\n",retval); +#endif + + if (retval==arg || arg<0) { + ret=OK; + } else { + ret=FAIL; + printf("Powering chip failed, wrote %d but read %d\n", arg, retval); + } + + } + if (ret==OK && differentClients==1) + ret=FORCE_UPDATE; + + /* send answer */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } else + n += sendDataOnly(file_des,&retval,sizeof(retval)); + + return ret; +} diff --git a/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.h b/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.h index 395f6f02c..0cbdd052b 100755 --- a/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.h +++ b/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.h @@ -97,4 +97,6 @@ int set_ctb_pattern(int); int write_adc_register(int);; int program_fpga(int); +int reset_fpga(int); +int power_chip(int); #endif diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp index dcade6b10..89fbf951a 100644 --- a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp @@ -3965,7 +3965,7 @@ int multiSlsDetector::programFPGA(string fname){ ret=detectors[i]->programFPGA(fname); if(detectors[i]->getErrorMask()) setErrorMask(getErrorMask()|(1<numberOfDetectors; i++) { + if (detectors[i]) { + ret=detectors[i]->resetFPGA(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; i++) { + if (detectors[i]) { + ret=detectors[i]->powerChip(ival); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<detectorMAC,detectorMAC.c_str()); if(!strcmp(thisDetector->receiver_hostname,"none")) - std::cout << "Warning: UDP Set up failed. Receiver hostname not set." << endl; + std::cout << "Warning: Receiver hostname not set yet." << endl; else if(setUDPConnection()==FAIL) std::cout<< "Warning: UDP connection set up failed" << std::endl; }else{ @@ -5526,7 +5526,7 @@ char* slsDetector::setDetectorIP(string detectorIP){ if(result!=0){ strcpy(thisDetector->detectorIP,detectorIP.c_str()); if(!strcmp(thisDetector->receiver_hostname,"none")) - std::cout << "Warning: UDP Set up failed. Receiver hostname not set." << endl; + std::cout << "Warning: Receiver hostname not set yet." << endl; else if(setUDPConnection()==FAIL) std::cout<< "Warning: UDP connection set up failed" << std::endl; }else{ @@ -5618,7 +5618,7 @@ char* slsDetector::setReceiverUDPIP(string udpip){ }else{ strcpy(thisDetector->receiverUDPIP,udpip.c_str()); if(!strcmp(thisDetector->receiver_hostname,"none")) - std::cout << "Warning: UDP Set up failed. Receiver hostname not set." << endl; + std::cout << "Warning: Receiver hostname not set yet." << endl; else if(setUDPConnection()==FAIL){ std::cout<< "Warning: UDP connection set up failed" << std::endl; } @@ -5641,7 +5641,7 @@ char* slsDetector::setReceiverUDPMAC(string udpmac){ (udpmac[11]==':')&&(udpmac[14]==':')){ strcpy(thisDetector->receiverUDPMAC,udpmac.c_str()); if(!strcmp(thisDetector->receiver_hostname,"none")) - std::cout << "Warning: UDP Set up failed. Receiver hostname not set." << endl; + std::cout << "Warning: Receiver hostname not set yet." << endl; else if(setUDPConnection()==FAIL){ std::cout<< "Warning: UDP connection set up failed" << std::endl; } @@ -5660,7 +5660,7 @@ char* slsDetector::setReceiverUDPMAC(string udpmac){ int slsDetector::setReceiverUDPPort(int udpport){ thisDetector->receiverUDPPort = udpport; if(!strcmp(thisDetector->receiver_hostname,"none")) - std::cout << "Warning: UDP Set up failed. Receiver hostname not set." << endl; + std::cout << "Warning: Receiver hostname not set yet." << endl; else if(setUDPConnection()==FAIL){ std::cout<< "Warning: UDP connection set up failed" << std::endl; } @@ -5670,7 +5670,7 @@ int slsDetector::setReceiverUDPPort(int udpport){ int slsDetector::setReceiverUDPPort2(int udpport){ thisDetector->receiverUDPPort2 = udpport; if(!strcmp(thisDetector->receiver_hostname,"none")) - std::cout << "Warning: UDP Set up failed. Receiver hostname not set." << endl; + std::cout << "Warning: Receiver hostname not set yet." << endl; else if(setUDPConnection()==FAIL){ std::cout<< "Warning: UDP connection set up failed" << std::endl; } @@ -5724,7 +5724,7 @@ int slsDetector::setUDPConnection(){ //called before set up if(!strcmp(thisDetector->receiver_hostname,"none")){ - std::cout << "Warning: UDP Set up failed. Receiver hostname not set." << endl; + std::cout << "Warning: Receiver hostname not set yet." << endl; return FAIL; } @@ -6430,12 +6430,18 @@ int slsDetector::writeSettingsFile(string fname, int imod, int* iodelay){ int slsDetector::programFPGA(string fname){ int ret=FAIL; + int fnum=F_PROGRAM_FPGA; + char mess[MAX_STR_LENGTH]=""; + int64_t retval = -1; + size_t filesize=0; + char* fpgasrc = NULL; if(thisDetector->myDetectorType != JUNGFRAU){ std::cout << "Not implemented for this detector" << std::endl; return FAIL; } + //check if it exists struct stat st; if(stat(fname.c_str(),&st)){ @@ -6443,7 +6449,6 @@ int slsDetector::programFPGA(string fname){ setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); return FAIL; } - //create destination file name,replaces original filename with Jungfrau.rawbin string destfname; size_t found = fname.find_last_of("/\\"); @@ -6452,8 +6457,6 @@ int slsDetector::programFPGA(string fname){ else destfname = fname.substr(0,found+1); destfname.append("Jungfrau_MCB.rawbin"); - - #ifdef VERBOSE std::cout << "Converting " << fname << " to " << destfname << std::endl; #endif @@ -6470,11 +6473,9 @@ int slsDetector::programFPGA(string fname){ 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) << (7-i) ); // This swaps the bits - fputc(y,dst); } if (filepos < 0x1000000){ @@ -6485,7 +6486,6 @@ int slsDetector::programFPGA(string fname){ #ifdef VERBOSE std::cout << "File has been converted to " << destfname << std::endl; #endif - //loading file to memory FILE* fp = fopen(destfname.c_str(),"r"); if(fp == NULL){ @@ -6498,14 +6498,14 @@ int slsDetector::programFPGA(string fname){ setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); return FAIL; } - size_t filesize = ftell(fp); - if(filesize == -1){ + filesize = ftell(fp); + if(filesize <= 0){ 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); + fpgasrc = (char*)malloc(filesize+1); if(fpgasrc == NULL){ std::cout << "Could not allocate size of program" << std::endl; setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); @@ -6526,14 +6526,8 @@ int slsDetector::programFPGA(string fname){ std::cout << "Successfully loaded the rawbin file to program memory" << 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 @@ -6541,7 +6535,6 @@ int slsDetector::programFPGA(string fname){ if (connectControl() == OK){ controlSocket->SendDataOnly(&fnum,sizeof(fnum)); controlSocket->SendDataOnly(&filesize,sizeof(filesize)); - //check opening error controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); if (ret==FAIL) { @@ -6551,6 +6544,8 @@ int slsDetector::programFPGA(string fname){ filesize = 0; } + + //erasing flash if(ret!=FAIL){ std::cout<< "This can take awhile. Please be patient..." << endl; printf("Erasing Flash:%d%%\r",0); @@ -6568,10 +6563,14 @@ int slsDetector::programFPGA(string fname){ std::cout << flush; } - //sending program in parts of 2mb each - while(filesize > 0){ - unitprogramsize = maxprogramsize; //2mb + //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; #ifdef VERBOSE @@ -6579,20 +6578,18 @@ int slsDetector::programFPGA(string fname){ #endif controlSocket->SendDataOnly(fpgasrc+currentPointer,unitprogramsize); controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); - if (ret==FAIL) { + if (ret!=FAIL) { + filesize-=unitprogramsize; + currentPointer+=unitprogramsize; + + //print progress + printf("Writing to Flash:%d%%\r",(int) (((double)(totalsize-filesize)/totalsize)*100)); + std::cout << flush; + }else{ controlSocket->ReceiveDataOnly(mess,sizeof(mess)); std::cout<< "Detector returned error: " << mess << std::endl; setErrorMask((getErrorMask())|(PROGRAMMING_ERROR)); - //stops writing - break; } - filesize-=unitprogramsize; - currentPointer+=unitprogramsize; - - //print progress - printf("Writing to Flash:%d%%\r",(int) (((double)(totalsize-filesize)/totalsize)*100)); - std::cout << flush; - } std::cout<myDetectorType != JUNGFRAU){ + std::cout << "Not implemented for this detector" << std::endl; + return FAIL; + } +#ifdef VERBOSE + std::cout<< "Sending reset to FPGA " << endl; +#endif + if (setOnline(ONLINE_FLAG)==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + + //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())|(RESET_ERROR)); + } + + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return ret; + +} + + + +int slsDetector::powerChip(int ival){ + int ret=FAIL; + int fnum=F_POWER_CHIP; + char mess[MAX_STR_LENGTH]=""; + int retval=-1; + + if(thisDetector->myDetectorType != JUNGFRAU){ + std::cout << "Not implemented for this detector" << std::endl; + return FAIL; + } +#ifdef VERBOSE + std::cout<< "Sending power on/off/get to the chip " << endl; +#endif + if (setOnline(ONLINE_FLAG)==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&ival,sizeof(ival)); + //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())|(POWER_CHIP)); + }else + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return retval; + +} int slsDetector::loadSettingsFile(string fname, int imod) { sls_detector_module *myMod=NULL; diff --git a/slsDetectorSoftware/slsDetector/slsDetector.h b/slsDetectorSoftware/slsDetector/slsDetector.h index 1f0cb7dfb..a3c6ff126 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.h +++ b/slsDetectorSoftware/slsDetector/slsDetector.h @@ -528,6 +528,18 @@ class slsDetector : public slsDetectorUtils, public energyConversion { */ int programFPGA(string fname); + /** resets FPGA + \returns OK or FAIL + */ + int resetFPGA(); + + /** power on/off the chip + \param ival on is 1, off is 0, -1 to get + \returns OK or FAIL + */ + int powerChip(int ival= -1); + + /** loads the modules settings/trimbits reading from a file \param fname file name . If not specified, extension is automatically generated! \param imod module number, -1 means all modules diff --git a/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp b/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp index 0accc5b6d..ddfd8fa43 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp @@ -441,10 +441,23 @@ slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAdvanced; i++; + + /* fpga */ + descrToFuncMap[i].m_pFuncName="programfpga"; descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAdvanced; i++; + descrToFuncMap[i].m_pFuncName="resetfpga"; + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAdvanced; + i++; + + + /* chip */ + descrToFuncMap[i].m_pFuncName="powerchip"; + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAdvanced; + i++; + /* versions/ serial numbers getId */ descrToFuncMap[i].m_pFuncName="moduleversion"; // @@ -4352,25 +4365,52 @@ string slsDetectorCommand::cmdAdvanced(int narg, char *args[], int action) { return myDet->externalSignalType(myDet->setExternalSignalFlags(flag,is)); - } else if (cmd=="programfpga") { + } + + + else if (cmd=="programfpga") { if (action==GET_ACTION) return string("cannot get"); - - if (narg<2) - return string("wrong usage: should specify programming file"); if(strstr(args[1],".pof")==NULL) - return string("wrong usage: should specify programming file with .pof extension"); - + return string("wrong usage: programming file should have .pof extension"); string sval=string(args[1]); #ifdef VERBOSE std::cout<< " programming file " << sval << std::endl; #endif + myDet->setOnline(ONLINE_FLAG); if(myDet->programFPGA(sval) == OK) - return string("programming successful"); - return string("programming unsuccessful"); + return string("successful"); + return string("unsuccessful"); + } + + + else if (cmd=="resetfpga") { + if (action==GET_ACTION) + return string("cannot get"); +#ifdef VERBOSE + std::cout<< " resetting fpga " << sval << std::endl; +#endif + myDet->setOnline(ONLINE_FLAG); + if(myDet->resetFPGA() == OK) + return string("successful"); + return string("unsuccessful"); + } + + + else if (cmd=="powerchip") { + char ans[100]; + myDet->setOnline(ONLINE_FLAG); + if (action==PUT_ACTION){ + int ival = -1; + if (!sscanf(args[1],"%d",&ival)) + return string("could not scan powerchip parameter " + string(args[1])); + myDet->powerChip(ival); + } + sprintf(ans,"%d",myDet->powerChip()); + return string(ans); } else - return string("could not decode flag ")+cmd; + return string("unknown command ")+cmd; } @@ -4382,8 +4422,8 @@ string slsDetectorCommand::helpAdvanced(int narg, char *args[], int action) { os << "extsig:i mode \t sets the mode of the external signal i. can be \n \t \t \t off, \n \t \t \t gate_in_active_high, \n \t \t \t gate_in_active_low, \n \t \t \t trigger_in_rising_edge, \n \t \t \t trigger_in_falling_edge, \n \t \t \t ro_trigger_in_rising_edge, \n \t \t \t ro_trigger_in_falling_edge, \n \t \t \t gate_out_active_high, \n \t \t \t gate_out_active_low, \n \t \t \t trigger_out_rising_edge, \n \t \t \t trigger_out_falling_edge, \n \t \t \t ro_trigger_out_rising_edge, \n \t \t \t ro_trigger_out_falling_edge" << std::endl; os << "flags mode \t sets the readout flags to mode. can be none, storeinram, tot, continous, parallel, nonparallel, safe, unknown" << std::endl; - os << "programfpga f \t programs the fpga with file f with .pof" << std::endl; - + 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; } if (action==GET_ACTION || action==HELP_ACTION) { diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUtils.h b/slsDetectorSoftware/slsDetector/slsDetectorUtils.h index 3e248bdc0..053a91c01 100644 --- a/slsDetectorSoftware/slsDetector/slsDetectorUtils.h +++ b/slsDetectorSoftware/slsDetector/slsDetectorUtils.h @@ -497,7 +497,16 @@ class slsDetectorUtils : public slsDetectorActions, public postProcessing { */ virtual int programFPGA(string fname)=0; + /** resets FPGA + \returns OK or FAIL + */ + virtual int resetFPGA()=0; + /** power on/off the chip + \param ival on is 1, off is 0, -1 to get + \returns OK or FAIL + */ + virtual int powerChip(int ival= -1)=0; /** saves the modules settings/trimbits writing to a file \param fname file name . Axtension is automatically generated!