/**************************************************************************** * * f1tdcConfig.c - configuration library file for JLAB F1 TDC board * * SP, 14-Jan-2014 * * empty lines and line startes with # - will be ignored * config file format: CRATE rocbcal1 <- ROC/crate name, usually IP name F1TDC_ALLSLOTS <- just keyword - all settings after this line will be implemented # for all slots, till F1TDC_SLOTS will be met F1TDC_SLOTS 3 8 19 <- slot_numbers - in which next settings will be implemented # till file ends or next F1TDC_SLOTS will be met F1TDC_F_REV 0x0e <- firmware revision (0x0 Bits:7-0) F1TDC_B_REV 0x02 <- board revision (0x0 Bits:15-8) F1TDC_ID 0x00f1 <- board type (0x0 Bits:31-16) # /---- slots ## # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 F1TDC_ALLSN 0 0 CQV2-13 CQV2-14 CQV2-15 CQV2-16 CQV2-17 CQV2-18 CQV2-44 CQV2-20 0 0 CQV2-23 CQV2-24 CQV2-25 CQV2-26 CQV2-27 CQV2-37 CQV2-38 CQV2-43 0 F1TDC_SL_SN 9 CQV2-44 <- single board Serial Number: sl# , SN F1TDC_CLOCK 0 <- Clock Source (0 = Internal 32 MHz) # (1 = External 31.25 MHz) F1TDC_VERSION 2 <- Module Version (2 = High Resolution, synchronous, 32 channels) # (3 = Normal Resolution, synchronous, 48 channels) F1TDC_BIN_SIZE 0.056 <- Bin size (ns) F1TDC_LATENCY 3000.0 <- Trigger latency (ns) F1TDC_WINDOW 1000.0 <- Trigger window (ns) # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - channels ## F1TDC_MASK1 1 1 1 1 1 1 1 0 0 0 1 1 0 1 1 0 <- enable mask for ch.0-15 F1TDC_MASK2 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 <- enable mask for ch.16-31 F1TDC_MASK3 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 <- enable mask for ch.32-47 cc -rdynamic -shared -o f1tdcConfig.so f1tdcConfig.c -I/home/halld/test_setup/coda/linuxvme/include /home/halld/test_setup/coda/linuxvme/jvme/libjvme.a /home/halld/test_setup/coda/linuxvme/f1tdc/libf1tdc.a -ldl -lpthread -lrt /home/halld/test_setup/coda/linuxvme/f1tdc/f1tdcLib.c /home/halld/test_setup/coda/linuxvme/f1tdc/f1tdcLib.h tcpClient rocbcal1 "f1Init(0x480000,0,0,0)" tcpClient rocbcal1 "f1tdcConfig('/home/halld/test_setup/rocbcal1/f1tdc_example.cnf')" tcpClient rocbcal1 "f1tdcMon(0,0)" tcpClient rocbcal1 "f1GStatus(0)" tcpClient rocbcal1 "f1GStatus(1)" tcpClient rocbcal1 "f1GStatus(2)" */ #if defined(VXWORKS) || defined(Linux_vme) #ifdef VXWORKS #include #include #include #else #include "jvme.h" #endif #include #include #include #include "f1tdcLib.h" #include "f1tdcConfig.h" #define FNLEN 128 /* length of config. file name */ #define STRLEN 250 /* length of str_tmp */ #define ROCLEN 80 /* length of ROC_name */ #define NBOARD 22 /* Global variables */ static int Nf1tdc = 0; /* Number of f1tdc in Crate */ static F1TDC_CONF f1[NBOARD]; static int f1tdc_clock = 0; static int f1tdc_version = 2;; static float f1tdc_bin_size = 0.056; static float f1tdc_latency = 3000.0; static float f1tdc_window = 1000.0; static unsigned int cfg_data[128]; static unsigned int t_offset; #define SCAN_MSK \ args = sscanf (str_tmp, "%*s %d %d %d %d %d %d %d %d \ %d %d %d %d %d %d %d %d", \ &msk[ 0], &msk[ 1], &msk[ 2], &msk[ 3], \ &msk[ 4], &msk[ 5], &msk[ 6], &msk[ 7], \ &msk[ 8], &msk[ 9], &msk[10], &msk[11], \ &msk[12], &msk[13], &msk[14], &msk[15]) #define F1TDC_B_XSCAN(BKEYWORD,BSTRUCT) \ else if(strcmp(keyword,(BKEYWORD)) == 0) \ { \ sscanf (str_tmp, "%*s %x", &ui1); \ for(ii=1; ii%s<\n",fname); return(-1); } } else /* filename does not specified */ { sprintf(fname, "%s/f1tdc/%s.cnf", halldparms, host); if((fd=fopen(fname,"r")) == NULL) { sprintf(fname, "%s/f1tdc/default.cnf", halldparms); if((fd=fopen(fname,"r")) == NULL) { printf("\nReadConfigFile: Can't open config file >%s<\n",fname); return(-2); } } } printf("\nReadConfigFile: Using configuration file >%s<\n",fname); /* Parsing of config file */ while ((ch = getc(fd)) != EOF) { if ( ch == '#' || ch == ' ' || ch == '\t' ) { while (getc(fd) != '\n') {} } else if( ch == '\n' ) {} else { ungetc(ch,fd); fgets(str_tmp, STRLEN, fd); sscanf (str_tmp, "%s %s", keyword, ROC_name); /* Start parsing real config inputs */ if(strcmp(keyword,"CRATE") == 0) { if(strcmp(ROC_name,host) != 0) { printf("\nReadConfigFile: Wrong crate name in config file, %s\n",str_tmp); return(-3); } printf("\nReadConfigFile: conf_CRATE_name = %s host = %s\n",ROC_name,host); } else if(strcmp(keyword,"F1TDC_ALLSLOTS") == 0) { gr++; for(ii=0; ii21) { printf("\nReadConfigFile: Wrong slot number %d, %s\n",slot,str_tmp); printf("\n Note: Acceptable slot number from 1 to 21\n"); return(-4); } f1[slot].group = gr; } } F1TDC_B_XSCAN("F1TDC_F_REV", f1[ii].f_rev) F1TDC_B_XSCAN("F1TDC_B_REV", f1[ii].b_rev) F1TDC_B_XSCAN("F1TDC_ID", f1[ii].b_ID) else if(strcmp(keyword,"F1TDC_ALLSN") == 0) { args = sscanf (str_tmp, "%*s %s %s %s %s %s %s %s %s %s %s \ %s %s %s %s %s %s %s %s %s %s %s", &sn[ 1], &sn[ 2], &sn[ 3], &sn[ 4], &sn[ 5], &sn[ 6], &sn[ 7], &sn[ 8], &sn[ 9], &sn[10], &sn[11], &sn[12], &sn[13], &sn[14], &sn[15], &sn[16], &sn[17], &sn[18], &sn[19], &sn[20], &sn[21]); if(args != 21) { printf("\nReadConfigFile: Wrong number of SNs %d, should be 21 :: %s\n\n",args,str_tmp); return(-5); } for(ii=1; ii20) { printf("\nReadConfigFile: Wrong slot number %d, %s\n",slot,str_tmp); return(-6); } sprintf((char *)f1[slot].SerNum, "%s", sn[0]); } else if(strcmp(keyword,"F1TDC_CLOCK") == 0) { sscanf (str_tmp, "%*s %d", &i1); if(i1!=0 && i1!=1) { printf("\nReadConfigFile: Wrong Clock Source %d, %s\n",i1,str_tmp); printf("\n Note: Acceptable Clock Source: 0 or 1\n"); return(-5); } f1tdc_clock = i1; } else if(strcmp(keyword,"F1TDC_VERSION") == 0) { sscanf (str_tmp, "%*s %d", &i1); if(i1!=2 && i1!=3) { printf("\nReadConfigFile: Wrong Module Version %d, %s\n",i1,str_tmp); printf("\n Note: Acceptable Module Version: 2 or 3\n"); return(-6); } f1tdc_version = i1; } else if(strcmp(keyword,"F1TDC_BIN_SIZE") == 0) { sscanf (str_tmp, "%*s %f", &flt1); if(flt1<0.0560 || flt1>0.0600) { printf("\nReadConfigFile: Wrong Bin size %f, %s\n",flt1,str_tmp); printf("\n Note: Acceptable 0.056 <= bin_size <= 0.06\n"); return(-7); } f1tdc_bin_size = flt1; } else if(strcmp(keyword,"F1TDC_LATENCY") == 0) { sscanf (str_tmp, "%*s %f", &flt1); bot = f1tdcConfLatencyBotLimit(); top = f1tdcConfLatencyTopLimit(); if(flt1<=bot || flt1>=top) { printf("\nReadConfigFile: Wrong Trigger latency %.1f, %s\n",flt1,str_tmp); printf("\n Note: Acceptable %.1f < latency < %.1f\n",bot,top); return(-8); } f1tdc_latency = flt1; } else if(strcmp(keyword,"F1TDC_WINDOW") == 0) { sscanf (str_tmp, "%*s %f", &flt1); bot = f1tdcConfWindowBotLimit(); top = f1tdcConfWindowTopLimit(); if(flt1<=bot || flt1>=top) { printf("\nReadConfigFile: Wrong Trigger window %.1f, %s\n",flt1,str_tmp); printf("\n Note: Acceptable %.1f < window < %.1f\n",bot,top); return(-9); } f1tdc_window = flt1; } else if(strncmp(keyword,"F1TDC_MASK",10) == 0) { SCAN_MSK; ui1 = 0; for(jj=0; jj 1)) { printf("\nReadConfigFile: Wrong mask bit value, %d\n\n",msk[jj]); return(-10); } ui1 |= (msk[jj]<2) { printf("ERROR: mask jj = %d, must be between 0 and 2\n",jj); return(-11); } /* printf("mask [jj=%d] = 0x%04x\n",jj,ui1); */ for(ii=0; ii> 8 ) & 0x7; refclkdiv = 1; for(ii = 0; ii < exponent; ii++) refclkdiv = 2 * refclkdiv; hsdiv = (clk_period/152.) * factor * ((float)refclkdiv)/bin_size_value + 0.5; /* force round up */ bin_size = factor * (clk_period/152.) * ( (float)refclkdiv )/( (float)hsdiv ); /* actual bin size */ full_range = 65536. * bin_size; refcnt = full_range/clk_period - 3.0; tframe = (float)(clk_period * (refcnt + 2 )); triglat = f1tdc_latency * factor/bin_size + 0.5; /* force round up */ trigwin = f1tdc_window * factor/bin_size + 0.5; /* force round up */ *(cfg_data + 7) = (0x8000) | ( (refcnt & 0x1FF) << 6 ); *(cfg_data + 8) = trigwin & 0xFFFF; *(cfg_data + 9) = triglat & 0xFFFF; *(cfg_data + 10) = (0x1F00) | (hsdiv & 0xFF); printf("\nf1tdc: clk=%d V=%d b_size=%.4f L=%.1f W=%.1f\n", f1tdc_clock,f1tdc_version,f1tdc_bin_size,f1tdc_latency,f1tdc_window); printf("full_range/clk_period - 3.0 = %.4f\n", (full_range/clk_period - 3.0)); printf("clk_period = %.2f refcnt = %d\n", clk_period, refcnt); printf("refclkdiv = %d hsdiv = %d bin_size (ns) = %.4f full_range (ns) = %.1f tframe (ns) = %.1f\n", refclkdiv,hsdiv,bin_size,full_range,tframe); /* unsigned long long int timestamp; unsigned long long int word=4; timestamp = (((unsigned long long)word&0xffffff)<<32); printf(" timestamp = %lld timestamp = 0x%llx)\n",timestamp,timestamp); */ for(ii = 1; ii < 8; ii++) /* copy reg 7,8,9,10 of chip 0 to chip 1-7 */ { cfg_offset = 16 * ii; *(cfg_data + cfg_offset + 7) = *(cfg_data + 7); *(cfg_data + cfg_offset + 8) = *(cfg_data + 8); *(cfg_data + cfg_offset + 9) = *(cfg_data + 9); *(cfg_data + cfg_offset + 10) = *(cfg_data + 10); } t_offset = tframe/bin_size; } void f1tdcWriteConfigDatFile() { FILE *fd; char dat_filename[FNLEN] = { "" }; /* config.dat file name */ char *getenv(); char *halldparms; int ii, jj; halldparms = getenv("HALLD_PARMS"); sprintf(dat_filename, "%s/f1tdc/default.dat", halldparms); fd = fopen(dat_filename,"w"); if(!fd) { printf("ERROR: Failed to open %s for writing\n",dat_filename); perror("fopen"); return; } for(ii = 0;ii < 8;ii++) /* write cfg_data to file */ { for(jj = 0;jj < 16;jj++) fprintf(fd,"%X ", *(cfg_data + (16*ii + jj)) ); fprintf(fd,"\n"); } fprintf(fd,"%d\n",t_offset); fclose(fd); } int f1tdcDownloadAll() { int slot, chan, ii; f1tdcModifyConfigData(); Nf1tdc = f1GetNf1tdc(); for(ii=0; ii= 0) { start = id; end = start + 1; } else { return; } for(ii=start; ii