From: Adrian Weber Date: Fri, 20 Apr 2018 09:43:42 +0000 (+0200) Subject: devTrbNet buxfixe for XML Format (now working with MDC.xml) X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=6b66901b49ece2141cec2a927808fc38aab30f55;p=epics.git devTrbNet buxfixe for XML Format (now working with MDC.xml) --- diff --git a/Trbnet/devTrbnet/TrbnetApp/Db/trbExample.substitutions b/Trbnet/devTrbnet/TrbnetApp/Db/trbExample.substitutions index 216963d..4c03ac8 100644 --- a/Trbnet/devTrbnet/TrbnetApp/Db/trbExample.substitutions +++ b/Trbnet/devTrbnet/TrbnetApp/Db/trbExample.substitutions @@ -1,3 +1,12 @@ file TrbnetApp/Db/trbExample.template { - {P=HAD:RICH:, TRBADDR=0x2220, REGADDR="3V8", TRBADDRWave=0x2220} + {P=HAD:MDC:TrbNet:,M="", TRBADDR=0xfffd, REGADDR="5V8", TRBADDRWave=0xfffd} + {P=HAD:MDC:TrbNet:,M="", TRBADDR=0xfffd, REGADDR="5V", TRBADDRWave=0xfffd} + {P=HAD:MDC:TrbNet:,M="", TRBADDR=0xfffd, REGADDR="3V8", TRBADDRWave=0xfffd} + {P=HAD:MDC:TrbNet:,M="", TRBADDR=0xfffd, REGADDR="3V3", TRBADDRWave=0xfffd} + {P=HAD:MDC:TrbNet:,M="", TRBADDR=0xfffd, REGADDR="1V8", TRBADDRWave=0xfffd} + {P=HAD:MDC:TrbNet:,M="", TRBADDR=0xfffd, REGADDR="1V2", TRBADDRWave=0xfffd} + {P=HAD:MDC:TrbNet:,M="", TRBADDR=0xfffd, REGADDR="p3V", TRBADDRWave=0xfffd} + {P=HAD:MDC:TrbNet:,M="", TRBADDR=0xfffd, REGADDR="m3V", TRBADDRWave=0xfffd} } + +# M is Moduel. e.g. "DIRICH:" \ No newline at end of file diff --git a/Trbnet/devTrbnet/TrbnetApp/Db/trbExample.template b/Trbnet/devTrbnet/TrbnetApp/Db/trbExample.template index bc57368..71d4b2a 100644 --- a/Trbnet/devTrbnet/TrbnetApp/Db/trbExample.template +++ b/Trbnet/devTrbnet/TrbnetApp/Db/trbExample.template @@ -13,50 +13,50 @@ #} -#record (waveform,"$(P)DiRICH:$(TRBADDRWave):READREGISTER:$(REGADDR)") -record (waveform,"$(P)DiRICH:$(TRBADDRWave):RREG:$(REGADDR)") +#record (waveform,"$(P)$(M)$(TRBADDRWave):READREGISTER:$(REGADDR)") +record (waveform,"$(P)$(M)$(TRBADDRWave):RREG:$(REGADDR)") { field( DESC, "Waveform of DiRich Temperatures.") field( SCAN , "5 second") field( DTYP, "devTrbnet" ) field( INP, "@TrbNet $(TRBADDRWave) $(REGADDR)" ) - field( NELM, "200") + field( NELM, "1000") field( FTVL, "DOUBLE") - field( FLNK, "$(P)DiRICH:$(TRBADDRWave):RREG:$(REGADDR):Calc_") + field( FLNK, "$(P)$(M)$(TRBADDRWave):RREG:$(REGADDR):Calc_") } -record(calcout, "$(P)DiRICH:$(TRBADDRWave):RREG:$(REGADDR):Calc_") +record(calcout, "$(P)$(M)$(TRBADDRWave):RREG:$(REGADDR):Calc_") { - field(INPA, "$(P)DiRICH:$(TRBADDRWave):RREG:$(REGADDR).NELM") + field(INPA, "$(P)$(M)$(TRBADDRWave):RREG:$(REGADDR).NELM") field(CALC, "A/2") - field(OUT, "$(P)DiRICH:$(TRBADDRWave):RREG:$(REGADDR):Testfan_.VAL PP") - #field(FLNK, "$(P)DiRICH:$(TRBADDRWave):RREG:$(REGADDR):Testfan_.PROC") + field(OUT, "$(P)$(M)$(TRBADDRWave):RREG:$(REGADDR):Testfan_.VAL PP") + #field(FLNK, "$(P)$(M)$(TRBADDRWave):RREG:$(REGADDR):Testfan_.PROC") } -record(dfanout, "$(P)DiRICH:$(TRBADDRWave):RREG:$(REGADDR):Testfan_") +record(dfanout, "$(P)$(M)$(TRBADDRWave):RREG:$(REGADDR):Testfan_") { - field(OUTA, "$(P)DiRICH:$(TRBADDRWave):RREG:$(REGADDR):SubArray.NELM PP") - field(OUTB, "$(P)DiRICH:$(TRBADDRWave):RREG:$(REGADDR):SubArray2.INDX") - field(OUTC, "$(P)DiRICH:$(TRBADDRWave):RREG:$(REGADDR):SubArray2.NELM PP") - #field(FLNK, "$(P)DiRICH:$(TRBADDRWave):RREG:$(REGADDR):SubArray.PROC") + field(OUTA, "$(P)$(M)$(TRBADDRWave):RREG:$(REGADDR):SubArray.NELM PP") + field(OUTB, "$(P)$(M)$(TRBADDRWave):RREG:$(REGADDR):SubArray2.INDX") + field(OUTC, "$(P)$(M)$(TRBADDRWave):RREG:$(REGADDR):SubArray2.NELM PP") + #field(FLNK, "$(P)$(M)$(TRBADDRWave):RREG:$(REGADDR):SubArray.PROC") } -record(subArray, "$(P)DiRICH:$(TRBADDRWave):RREG:$(REGADDR):SubArray") +record(subArray, "$(P)$(M)$(TRBADDRWave):RREG:$(REGADDR):SubArray") { field(DESC, "lower half") field(DTYP, "Soft Channel") field(MALM, "1024") field(INDX, "0") field(FTVL, "DOUBLE") - field(INP, "$(P)DiRICH:$(TRBADDRWave):RREG:$(REGADDR).VAL") + field(INP, "$(P)$(M)$(TRBADDRWave):RREG:$(REGADDR).VAL") } -record(subArray, "$(P)DiRICH:$(TRBADDRWave):RREG:$(REGADDR):SubArray2") +record(subArray, "$(P)$(M)$(TRBADDRWave):RREG:$(REGADDR):SubArray2") { field(DESC, "Upper half") field(DTYP, "Soft Channel") - field(INP, "$(P)DiRICH:$(TRBADDRWave):RREG:$(REGADDR)") + field(INP, "$(P)$(M)$(TRBADDRWave):RREG:$(REGADDR)") field(FTVL, "DOUBLE") field(MALM, "1024") } diff --git a/Trbnet/devTrbnet/TrbnetApp/Db/trbExample_copy.substitutions_copy b/Trbnet/devTrbnet/TrbnetApp/Db/trbExample_copy.substitutions_copy new file mode 100644 index 0000000..a02dc5a --- /dev/null +++ b/Trbnet/devTrbnet/TrbnetApp/Db/trbExample_copy.substitutions_copy @@ -0,0 +1,16 @@ +file trbExample.template { +# {TRBADDR=0x1201, REGADDR=Temperature, TRBADDRWave=0xFE51} +{TRBADDR=0xffff, REGADDR=Temperature, TRBADDRWave=0xffff} +#{TRBADDR=0x8300, REGADDR=ADC_2, TRBADDRWave=0x8300} +#{TRBADDR=0x8300, REGADDR=ADC_1, TRBADDRWave=0x8300} +#{TRBADDR=0x8300, REGADDR=ADC_0, TRBADDRWave=0x8300} + +#{TRBADDR=0x1201, REGADDR=Temperature, TRBADDRWave=0x1201} +#{TRBADDR=0x0202, REGADDR=0xc804} +#{TRBADDR=0x0203, REGADDR=0xc804} +} + +file trbADC.template { + {TRBADDR=0x8300, REGADDR=ADC_3, TRBADDRWave=0x8300} + {TRBADDR=0xe600, REGADDR=ADC_1, TRBADDRWave=0x1226} +} diff --git a/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet.c b/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet.c index 9609ddd..47567e9 100644 --- a/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet.c +++ b/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet.c @@ -361,11 +361,12 @@ static long initCommon( dbCommon* prec, DBLINK* plink ) { } //read the entity-file from cache - int gaddress=-1; + int gaddress = -1; + int Entity_addr = -1; int raddress=-1,bits=0,start=0,rate=0,unit=0; float scale=0.; - bool register_open=false,field_open=false,group_open=false; - char node[20]="",gname[25]="",gmode[2]="",rname[25]="",purpose[25]="",fname[20]="",fformat[10]=""; + bool register_open=false,field_open=false,group_open=false,Entity_open=false; + char node[20]="",gname[25]="",gmode[2]="",rname[25]="",purpose[25]="",fname[20]="",fformat[10]="", Entity_name[25]=""; int trb_status; char* filepath = getenv("EPICS_TRBNET_XML_PATH"); //char* name = {"TrbNet"}; @@ -384,9 +385,26 @@ static long initCommon( dbCommon* prec, DBLINK* plink ) { char delimiter[] = " "; char *ptr; ptr = strtok(linebuffer, delimiter); - sscanf(ptr, "%s", node); - ptr = strtok(NULL, delimiter); + sscanf(ptr, "%s", node); + //printf("%s \n", node); + ptr = strtok(NULL, delimiter); + if (strcmp(node,"") == 0){ + Entity_open = false; + //printf("Entity_Close\n"); + } + if (strcmp(node,"reg_addr = (epicsUInt16)( (reg_addr_buf + gaddress) & 0xffff ); - for (i=0; i < NumberOfBoards; i++){ - trb[i].Reg[trb[i].used-1].regAddr = pinfo->reg_addr; - } - } - if(sscanf(ptr, "name=\"%[A-z,_0-9]\"", rname)==1){ - for (i=0; i < NumberOfBoards; i++){ - trb[i].Reg[trb[i].used-1].name = strdup(rname); - printf("RNAME: %s\n", rname); - } - } - if(sscanf(ptr, "purpose=\"%[A-z,_0-9]\"", purpose)==1){ - for (i=0; i < NumberOfBoards; i++){ - trb[i].Reg[trb[i].used-1].purpose = strdup(purpose); - } - } - } - - if (field_open==true && group_open==true && register_open==true){ - if (strcmp(ptr,"/>\n") == 0){ - field_open=false; - } - if (sscanf(ptr, "name=\"%[A-z,_0-9]\"", fname)==1){ - for (i=0; i < NumberOfBoards; i++){ - trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].name = strdup(fname); - printf(" FNAME: %s %i\n", rname,NumberOfBoards); - - } - } - if (sscanf(ptr, "format=\"%[A-z,_0-9]\"", fformat)==1){ - for (i=0; i < NumberOfBoards; i++){ - trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].format = strdup(fformat); - } - } - if (sscanf(ptr, "bits=%*c%i%*c", &bits)==1){ - for (i=0; i < NumberOfBoards; i++){ - trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].bits = bits; - } - } - if (sscanf(ptr, "start=%*c%i%*c", &start)==1){ - for (i=0; i < NumberOfBoards; i++){ - trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].start = start; - } - } - if (sscanf(ptr, "rate=%*c%i%*c", &rate )==1){ - for (i=0; i < NumberOfBoards; i++){ - trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].rate = rate; - } - } - if (sscanf(ptr, "unit=%*c%x%*c", &unit )==1){ - for (i=0; i < NumberOfBoards; i++){ - trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].unit = unit; - } - } - if (sscanf(ptr, "scale=%*c%f%*c", &scale )==1){ - for (i=0; i < NumberOfBoards; i++){ - trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].scale = scale; - } - } - } + //} else { + if (group_open==true && register_open==false && field_open==false) { + sscanf(ptr, "address=\"%x\"", &gaddress); + sscanf(ptr, "name=\"%[A-z,_0-9]\"", gname); + sscanf(ptr, "mode=\"%[A-z,_,0-9]\"", gmode); + } + if (register_open==true && group_open==true && field_open==false){ + if(sscanf(ptr, "address=\"%x\"", ®_addr_buf)==1){ + pinfo->reg_addr = (epicsUInt16)( (reg_addr_buf + gaddress + Entity_addr) & 0xffff ); + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].regAddr = pinfo->reg_addr; + } + } + if(sscanf(ptr, "name=\"%[A-z,_0-9]\"", rname)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].name = strdup(rname); + //printf("RNAME: %s\n", rname); + } + } + + if(sscanf(ptr, "purpose=\"%[A-z,_0-9]\"", purpose)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].purpose = strdup(purpose); + } + } + } + if (field_open==true && group_open==true && register_open==true){ + int len = strlen(ptr); + const char *last_three = &ptr[len-3]; + //printf("%s\n", last_three); + if (strcmp(ptr,"/>\n") == 0){ + field_open=false; + } + + if (strcmp(last_three,"/>\n") == 0){ + field_open=false; + } + + if (sscanf(ptr, "name=\"%[A-z,_0-9]\"", fname)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].name = strdup(fname); + //printf(" FNAME: %s %i\n", rname,NumberOfBoards); + + } + } + if (sscanf(ptr, "format=\"%[A-z,_0-9]\"", fformat)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].format = strdup(fformat); + } + } + if (sscanf(ptr, "bits=%*c%i%*c", &bits)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].bits = bits; + } + } + if (sscanf(ptr, "start=%*c%i%*c", &start)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].start = start; + } + } + if (sscanf(ptr, "rate=%*c%i%*c", &rate )==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].rate = rate; + } + } + if (sscanf(ptr, "unit=%*c%x%*c", &unit )==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].unit = unit; + } + } + if (sscanf(ptr, "scale=%*c%f%*c", &scale )==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].scale = scale; + } + } + } + //} ptr = strtok(NULL, delimiter); }//end while2 }//end while1 +//printf("Entity_address: %i\n", Entity_addr); +//printf("Entity_Name %s \n",Entity_name); fclose(fp); databaseSet = 1; @@ -497,16 +526,16 @@ static long initCommon( dbCommon* prec, DBLINK* plink ) { fprintf( stderr, "\033[31;1m%s: Invalid register address '%x'\033[0m\n",prec->name, reg_addr_buf ); return -1; } -printf("%i\n",__LINE__); +//printf("%i\n",__LINE__); //----------------------------------------------------------------------// - // Test the fields - printf("Register Addres: %i\n", trb[0].Reg[2].regAddr); // getAddr of Register[0] +/* // Test the fields + printf("Register Addres: 0x%4x\n", trb[0].Reg[2].regAddr); // getAddr of Register[0] printf("Number of registers: %i\n", trb[0].size); // print number of fields in Register printf("Number of fields:%i\n", trb[0].Reg[1].size); // print name of field 1 in Register 0 printf("Number of fields:%s\n", trb[0].Reg[2].field[0].name); // print name of field 1 in Register 0 printf("%i\n", trb[0].used); // getAddr of Register[0] - +*/ //---------------------------------------------------------------------------------------------// /*free memory for(i=0;idpvt; epicsUInt32 *pdata_buf; - epicsUInt32 count = 200;//prec->nelm; // equal to 100 boards + epicsUInt32 count = 2000;//prec->nelm; // equal to 100 boards int trb_stat = 0; int i = 0; -printf("%i\n",__LINE__); + if( !_trb_connected ) { if( init_ports() == -1 ) { @@ -717,9 +746,9 @@ printf("%i\n",__LINE__); } _trb_connected = true; } - printf("%i\n",__LINE__); +; pdata_buf = callocMustSucceed( count, sizeof(epicsUInt32), "devTrbnet::processWaveform" ); - printf("%i\n",__LINE__); + int j,k,address; int search_stat = -1 ; int trb_Nmb=0, reg_Nmb=0, field_Nmb=0; @@ -727,41 +756,47 @@ printf("%i\n",__LINE__); if (strcmp(pinfo->reg_name_buf, "ADC") == 0){ search_stat = 1; } else { -printf("%i\n",__LINE__); + for(i=0;i= 0){ printf("%i\n",__LINE__); + //printf("%i %i %i\n",i,j,__LINE__); + if (search_stat >= 0){ //printf("%i\n",__LINE__); //run without doing smtng } else { - printf("%i %i %i\n",i,j,__LINE__); - printf("trb %s \n",trb[i].Reg[j].name); - printf("pinfo %s \n",pinfo->reg_name_buf); - printf("comp %i \n",strcmp(trb[i].Reg[j].name,pinfo->reg_name_buf)); - if (strcmp(trb[i].Reg[j].name,pinfo->reg_name_buf) == 0){ - search_stat = 0; printf("%i %i %i\n",i,j,__LINE__); - } - else { - printf("%i\n",__LINE__); - for(k=0;kreg_name_buf)); - - if (strcmp(trb[i].Reg[j].field[k].name, pinfo->reg_name_buf) == 0){ - address = trb[i].Reg[j].field[k].regAddr; - search_stat = 0; - trb_Nmb=i; reg_Nmb=j; field_Nmb=k; - } else { - search_stat = -1; - } - } - } + /*printf("%i %i %i\n",i,j,__LINE__); + printf("trb %s \n",trb[i].Reg[j].name); + printf("pinfo %s \n",pinfo->reg_name_buf); + printf("comp %i \n",strcmp(trb[i].Reg[j].name,pinfo->reg_name_buf)); + */ + if (strcmp(trb[i].Reg[j].name,pinfo->reg_name_buf) == 0){ + search_stat = 0; + //printf("%i %i %i\n",i,j,__LINE__); + //printf("NAME: %s \n",trb[i].Reg[j].name); + //printf("ADDR: 0x%4x \n",trb[i].Reg[j].regAddr); + address = trb[i].Reg[j].regAddr; + + trb_Nmb=i; reg_Nmb=j; + } + else { + //printf("%i\n",__LINE__); + for(k=0;kreg_name_buf)); + + if (strcmp(trb[i].Reg[j].field[k].name, pinfo->reg_name_buf) == 0){ + address = trb[i].Reg[j].field[k].regAddr; + search_stat = 0; + trb_Nmb=i; reg_Nmb=j; field_Nmb=k; + } else { + search_stat = -1; + } + } + } }//search_stat end if } } - } -printf("%i\n",__LINE__); +//printf("%i\n",__LINE__); int data_size = 2; unsigned int mode = 0; diff --git a/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet.c_backup b/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet.c_backup new file mode 100644 index 0000000..d9a3ce1 --- /dev/null +++ b/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet.c_backup @@ -0,0 +1,871 @@ +/****** I N C L U D E S *******************************************************/ + +/* ANSI C includes */ +#include +#include +#include +#include +#include + +/* EPICS includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* local includes */ +#include "trberror.h" +#include "trbnet.h" + + +#define LINELENGTH 250 + +#define NumberOfBoards 1 + +#define __Name 0 +#define __Scale 1 +#define __Unit 2 +#define __Format 3 +#define __Start 4 +#define __Bits 5 +#define __Rate 6 +#define __ErrorFlag 7 +#define __InvertFlag 8 +#define __Value 9 + +/****** D E F I N I T I O N S **************************************************/ +static long initLi( longinRecord* prec ); +static long initLo( longoutRecord* prec ); +static long initWaveform( waveformRecord* prec ); +static long processLi( longinRecord* prec ); +static long processLo( longoutRecord* prec ); +static long processWaveform( waveformRecord* prec ); + +typedef struct { + long number; + DEVSUPFUN dev_report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN process; +} dev_dset_trbnet_t; + +typedef struct { + epicsUInt16 trb_addr; + char* reg_name_buf; + char* reg_name_buf_nbr; + epicsUInt16 reg_addr; + //char entity_name[20]; +} trbnet_info_t; + +typedef struct{ + epicsUInt16 regAddr; + char *name; + float scale; + char *unit; + char *format; + int start; + int bits; + int rate; + char *errorflag; + char *invertflag; + int value; +}field_struct; + +typedef struct{ + epicsUInt16 regAddr; + char *name; + char *purpose; + field_struct *field; + int size; + int used; + int value; +}reg_struct; + +typedef struct{ + epicsUInt16 address; + char *name; + reg_struct *Reg; + size_t size; + size_t used; +}trb_struct; + +/****** G L O B A L S **********************************************************/ +dev_dset_trbnet_t dev_trbnet_li = { 6, NULL, NULL, initLi, NULL, processLi }; +dev_dset_trbnet_t dev_trbnet_lo = { 6, NULL, NULL, initLo, NULL, processLo }; +dev_dset_trbnet_t dev_trbnet_waveform = { 6, NULL, NULL, initWaveform, NULL, processWaveform }; +trb_struct *trb; +int databaseSet = 0; + +/****** L O C A L S ************************************************************/ +static bool _trb_connected = false; + +/****** F U N C T I O N S ******************************************************/ + +epicsExportAddress( dset, dev_trbnet_li ); +epicsExportAddress( dset, dev_trbnet_lo ); +epicsExportAddress( dset, dev_trbnet_waveform ); + +/*----- TEST FUNKTION ---------------------------------------------------------*/ +int trb_register_readTESTFUNKTION( uint16_t trb_addr, + uint16_t addr, + uint32_t *data, + unsigned int dsize) +{ + int status = 0; + if (trb_addr== 0) { + if (addr== 0) { + data[0] = 0; + //data[1]=21400000; + data[1] = 557842432; + } + return 2; + } + else if(trb_addr == 1) { + data[0] = 0; + data[1] = 557842432; + data[2] = 1; + data[3] = 557845532; + data[4] = 2; + data[5] = 557823451; + data[6] = 3; + data[7] = 557733332; + data[8] = 4; + data[9] = 667823451; + data[10] = 5; + data[11] = 598733332; + return 12; + } else { + return -1; + } +} + +int PadiwaSendCmd(uint32_t cmd, uint32_t board, uint32_t chain) { + + uint32_t c[] = { cmd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1<Reg[RegNumb].field = (field_struct *)malloc(sizeof(field_struct)); // 1 field + trb->Reg[RegNumb].used = 0; + trb->Reg[RegNumb].size = 1; + //Init with start values + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].regAddr = trb->Reg[RegNumb].regAddr; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].name = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].scale = 1; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].unit = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].format = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].start = 0; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].bits = 32; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].rate = -1; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].errorflag = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].invertflag = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].value = -1; +} + +void initReg(trb_struct *trb, size_t initialSize) { + trb->Reg = (reg_struct *)malloc(initialSize * sizeof(reg_struct)); + trb->used = 0; + trb->size = initialSize; + int i=0; + for ( i; i < initialSize; i++) { + initField(trb, i); // trb_struct; i01= Element of Register + } +} + +// Insert a new field. Only RegAddress is Set from default +void insertField(reg_struct *reg) { + if (reg->used == reg->size) { + reg->size++; + reg->field = (field_struct *)realloc(reg->field, reg->size * sizeof(field_struct)); + } + //Init with start values + reg->field[reg->used].regAddr = reg->regAddr; //set register Address + reg->field[reg->used].name = NULL; + reg->field[reg->used].scale = 1; + reg->field[reg->used].unit = NULL; + reg->field[reg->used].format = NULL; + reg->field[reg->used].start = 0; + reg->field[reg->used].bits = 32; + reg->field[reg->used].rate = -1; + reg->field[reg->used].errorflag = NULL; + reg->field[reg->used].invertflag = NULL; + reg->field[reg->used].value = -1; + reg->used++; +} + +int setFieldPropertyInt(reg_struct *reg,int fieldNmb, int element, int data) { + if (fieldNmb < reg->used) { + if (element == __Start){ //field start + reg->field[fieldNmb].start = data; + } else if (element == __Bits){ //field bits + reg->field[fieldNmb].bits = data; + } else if (element == __Rate){ //field rate + reg->field[fieldNmb].rate = data; + } else if (element == __Value){ //field ratevalue + reg->field[fieldNmb].value = data; + } else { + printf("Element does not Fit to a INT Type property.\n"); + } + return 0; + } else { + return 1; //Error + } +} + +int setFieldPropertyStr(reg_struct *reg,int fieldNmb, int element, char *data) { + if (fieldNmb < reg->used) { + if(element == __Name){ //field NAME + reg->field[fieldNmb].name =strdup(data); + } else if (element == __Unit){ //field UNIT + reg->field[fieldNmb].unit = strdup(data); + } else if (element == __Format){ //field format + reg->field[fieldNmb].format = strdup(data); + } else if (element == __ErrorFlag){ //field errorflag + reg->field[fieldNmb].errorflag = strdup(data); + } else if (element == __InvertFlag){//field invertflag + reg->field[fieldNmb].invertflag = strdup(data); + } else { + printf("Element does not Fit to a STRING Type property.\n"); + } + return 0; + } else { + return 1; //Error; Field does not exist + } +} + +int setFieldPropertyFloat(reg_struct *reg, int fieldNmb, int element, float data) { + if (fieldNmb < reg->used) { + if (element == __Scale){ //field SCALE + reg->field[fieldNmb].scale = data; + } else { + printf("Element does not Fit to a FLOAT Type property.\n"); + } + return 0; + } else { + return 1; //Error; Field does not exist + } +} + +void insertReg(trb_struct *trb, int element) { + if (trb->used == trb->size) { + trb->size++; + trb->Reg = (reg_struct *)realloc(trb->Reg, trb->size * sizeof(reg_struct)); + } + trb->Reg[trb->used].regAddr = element; + initField(trb, trb->used); + trb->used++; +} + +// free the allocated memory of the fields of each Register +void freeField(trb_struct *trb) { + int i=0; + for (i;iused;i++){ + free(trb->Reg[i].field); + trb->Reg[i].field = NULL; + trb->Reg[i].used = trb->Reg[i].size = 0; + } +} + +// free the allocated memory of each register +void freeReg(trb_struct *trb) { + freeField(trb); + free(trb->Reg); + trb->Reg = NULL; + trb->used = trb->size = 0; +} + +/*----- Common initialization for all records ---------------------------------*/ + +static long initCommon( dbCommon* prec, DBLINK* plink ) { + + trbnet_info_t *pinfo; + char entity_name_buf[20] = ""; + char Reg_name_buf[20] = ""; + epicsUInt32 trb_addr_buf = 0; + epicsUInt32 reg_addr_buf = 0; + + char linebuffer[LINELENGTH]; + + if ( sscanf( plink->value.instio.string, "%s %x %s", entity_name_buf, &trb_addr_buf, Reg_name_buf ) != 3 ) { + fprintf( stderr, "\033[31;1m%s: Invalid value of INP/OUT field '%s'\033[0m\n", + prec->name, plink->value.instio.string ); + return -1; + } + if ( 0xffff < trb_addr_buf ) { + fprintf( stderr, "\033[31;1m%s: Invalid trb address '%x'\033[0m\n", + prec->name, trb_addr_buf ); + return -1; + } + + pinfo = callocMustSucceed( 1, sizeof(*pinfo), "devTrbnet::initCommon" ); + pinfo->trb_addr = (epicsUInt16)( trb_addr_buf & 0xffff ); +// pinfo->reg_name_buf = strdup(Reg_name_buf); + prec->dpvt = pinfo; + prec->udf = FALSE; + int i=0; + + // check special cases that are not inb XMLS Database + char * pname; +// char reg_name_buf[30]; +// strcpy(reg_name_buf, pinfo->reg_name_buf); + pname = strtok(Reg_name_buf,"_"); + pinfo->reg_name_buf = strdup(pname); + + while (pname != NULL){ +// printf("Ausgabe: %s\n",pname); + pinfo->reg_name_buf_nbr = strdup(pname); + pname = strtok(NULL," "); + + } +printf("test: %s\n",pinfo->reg_name_buf); +printf("test2: %s\n",pinfo->reg_name_buf_nbr); +//----------------------------------------------------------------// + + + +// create Memory for each TrbBoard + if (databaseSet==0) + { + trb = (trb_struct *) malloc(NumberOfBoards * sizeof(trb_struct)); + + for(i=0;i") == 0){ + group_open = false; + } + if (strcmp(node,"") == 0){ + register_open = false; + } + if (strcmp(node,"") == 0){ + field_open = false; + } + + // analyse each part of one line of .xml document + while(ptr != NULL) { + + if (group_open==true && register_open==false && field_open==false) { + sscanf(ptr, "address=\"%x\"", &gaddress); + sscanf(ptr, "name=\"%[A-z,_0-9]\"", gname); + sscanf(ptr, "mode=\"%[A-z,_,0-9]\"", gmode); + } + if (register_open==true && group_open==true && field_open==false){ + if(sscanf(ptr, "address=\"%x\"", ®_addr_buf)==1){ + pinfo->reg_addr = (epicsUInt16)( (reg_addr_buf + gaddress) & 0xffff ); + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].regAddr = pinfo->reg_addr; + } + } + if(sscanf(ptr, "name=\"%[A-z,_0-9]\"", rname)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].name = strdup(rname); + } + } + + if(sscanf(ptr, "purpose=\"%[A-z,_0-9]\"", purpose)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].purpose = strdup(purpose); + } + } + } + + if (field_open==true && group_open==true && register_open==true){ + if (strcmp(ptr,"/>\n") == 0){ + field_open=false; + } + if (sscanf(ptr, "name=\"%[A-z,_0-9]\"", fname)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].name = strdup(fname); + } + } + if (sscanf(ptr, "format=\"%[A-z,_0-9]\"", fformat)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].format = strdup(fformat); + } + } + if (sscanf(ptr, "bits=%*c%i%*c", &bits)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].bits = bits; + } + } + if (sscanf(ptr, "start=%*c%i%*c", &start)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].start = start; + } + } + if (sscanf(ptr, "rate=%*c%i%*c", &rate )==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].rate = rate; + } + } + if (sscanf(ptr, "unit=%*c%x%*c", &unit )==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].unit = unit; + } + } + if (sscanf(ptr, "scale=%*c%f%*c", &scale )==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].scale = scale; + } + } + } + + ptr = strtok(NULL, delimiter); + }//end while2 + }//end while1 + + fclose(fp); + databaseSet = 1; + } + if ( 0xffff < reg_addr_buf ) { + fprintf( stderr, "\033[31;1m%s: Invalid register address '%x'\033[0m\n",prec->name, reg_addr_buf ); + return -1; + } + +//----------------------------------------------------------------------// + +/* // Test the fields + printf("Register Addres: %i\n", trb[0].Reg[8].regAddr); // getAddr of Register[0] + printf("Number of registers: %i\n", trb[0].size); // print number of fields in Register + printf("Number of fields:%i\n", trb[0].Reg[0].size); // print name of field 1 in Register 0 + printf("Number of fields:%s\n", trb[0].Reg[1].field[0].name); // print name of field 1 in Register 0 + printf("%i\n", trb[0].used); // getAddr of Register[0] +*/ +//---------------------------------------------------------------------------------------------// + /*free memory + for(i=0;ipact = (epicsUInt8)true; /* disable record */ + + status = initCommon( (dbCommon *)prec, &prec->inp ); + prec->pact = (epicsUInt8)false; /* enable record */ + + return status; +} + +/*----- initialization of longout records -------------------------------------*/ +static long initLo( longoutRecord* prec ) { + long status = 0; + prec->pact = (epicsUInt8)true; /* disable record */ + + status = initCommon( (dbCommon *)prec, &prec->out ); + prec->pact = (epicsUInt8)false; /* enable record */ + + return status; +} + +/*----- initialization of waveform records ------------------------------------*/ +static long initWaveform( waveformRecord* prec ) { + long status = 0; + prec->pact = (epicsUInt8)true; /* disable record */ + + if ( DBF_DOUBLE != prec->ftvl ) { + fprintf( stderr, "\033[31;1m%s: Invalid field type of value\033[0m\n", prec->name ); + return -1; + } + + status = initCommon( (dbCommon *)prec, &prec->inp ); + prec->pact = (epicsUInt8)false; /* enable record */ + + return status; +} + +/*----- process routine of longin records -------------------------------------*/ +static long processLi( longinRecord* prec ) { + trbnet_info_t* pinfo = (trbnet_info_t*)prec->dpvt; + epicsUInt32 data[2] = { 0 }; + int trb_stat = 0; + + int j,k,i,address; + int search_stat = 0 ; + int trb_Nmb=0, reg_Nmb=0, field_Nmb=0; + + if( !_trb_connected ){ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); // could be a problem (prec->name) + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + _trb_connected = true; + } + + + + // READ Address from Database + for(i=0;ireg_name_buf) == 0){ + search_stat = 0; + } + else { + for(k=0;kreg_name_buf) == 0){ + address = trb[i].Reg[j].field[k].regAddr; + search_stat = 0; + trb_Nmb=i; reg_Nmb=j; field_Nmb=k; + } else { + search_stat = -1; + } + } + } + } + } + + if (search_stat){ + int data_size = 2; + trb_stat = trb_register_read( pinfo->trb_addr, address, data, data_size ); + //trb_stat = trb_register_readTESTFUNKTION( pinfo->trb_addr, address, data, data_size ); + + //--------------------------------------// + if ( -1 == trb_stat ) { + /* first try failed, do it again */ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + trb_stat = trb_register_read( pinfo->trb_addr, address, data, data_size ); + if ( -1 == trb_stat ) { + /* second try failed, return error */ + fprintf( stderr, "\033[31;1m%s: read_register failed: %d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, READ_ALARM, INVALID_ALARM ); + _trb_connected = false; + return -1; + } + } + /* Check Status-Bits */ + if ( TRB_STATUS_WARNING == trb_errno ) { + fprintf( stderr, "%s: Warning: Status-Bit(s) have been set:\n%s\n", + prec->name, trb_termstr( trb_term ) ); + recGblSetSevr( prec, NULL, NULL); + return -1; + } + //------------------------------// + double output = -1; + epicsUInt32 start = pow(2, trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].start); + epicsUInt32 end = pow(2, trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].bits); + double scale = trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].scale; + + for (i=0; i< data_size;i+=2){ + output = ((data[i+1]/start)%end )*scale; + prec->val = output; + } + //--------------------------------// + + } else { + printf("No Address Name %s found!\n", pinfo->reg_name_buf); + } + + + return 0; +} + +//----- LONGOUT IS NOT IN USE!!!-----------------------------------------------// +/*----- process routine of longout records ------------------------------------*/ +static long processLo( longoutRecord* prec ) { + trbnet_info_t* pinfo = (trbnet_info_t*)prec->dpvt; + epicsUInt32 value = prec->val; + int trb_stat = 0; + + if( !_trb_connected ) { + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + _trb_connected = true; + } + + trb_stat = trb_register_write( pinfo->trb_addr, pinfo->reg_addr, value ); + if ( -1 == trb_stat ) { + /* first try failed, do it again */ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + trb_stat = trb_register_write( pinfo->trb_addr, pinfo->reg_addr, value ); + if ( -1 == trb_stat ) { + /* second try failed, return error */ + fprintf( stderr, "\033[31;1m%s: write_register failed: %d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, WRITE_ALARM, INVALID_ALARM ); + _trb_connected = false; + return -1; + } + } + if ( TRB_STATUS_WARNING == trb_errno ) { + fprintf( stderr, "%s: Warning: Status-Bit(s) have been set:\n%s\n", + prec->name, trb_termstr( trb_term ) ); + return -1; + } + + return 0; +} + +/*----- process routine of waveform records -----------------------------------*/ +static long processWaveform( waveformRecord* prec ) { + trbnet_info_t *pinfo = (trbnet_info_t*)prec->dpvt; + epicsUInt32 *pdata_buf; + epicsUInt32 count = 200;//prec->nelm; // equal to 100 boards + int trb_stat = 0; + int i = 0; + + + if( !_trb_connected ) { + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed TEST:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); // same as above + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + _trb_connected = true; + } + + pdata_buf = callocMustSucceed( count, sizeof(epicsUInt32), "devTrbnet::processWaveform" ); + + int j,k,address; + int search_stat = -1 ; + int trb_Nmb=0, reg_Nmb=0, field_Nmb=0; + + if (strcmp(pinfo->reg_name_buf, "ADC") == 0){ + search_stat = 1; +} else { + + for(i=0;i= 0){ + //run without doing smtng + } else { + if (strcmp(trb[i].Reg[j].name,pinfo->reg_name_buf) == 0){ + search_stat = 0; + } + else { + for(k=0;kreg_name_buf)); + + if (strcmp(trb[i].Reg[j].field[k].name, pinfo->reg_name_buf) == 0){ + address = trb[i].Reg[j].field[k].regAddr; + search_stat = 0; + trb_Nmb=i; reg_Nmb=j; field_Nmb=k; + } else { + search_stat = -1; + } + } + } + }//search_stat end if + } + } + +} + + int data_size = 2; + unsigned int mode = 0; + + if (search_stat == 1){ + int channel[5] = {7,7,7,6,5}; + int resolution[5][4] = {{2,1,2,1},{2,2,2,1},{2,2,2,4},{2,2,2,2},{3,3,2,2}}; + double multiplier[5][4] = {{1.,1.,0.5,2.},{1.,1.,0.5,0.},{1.,1.,0.5,3.125},{1.,1.,0.5,0.5},{2.5,1.25,1.,0.5}}; + int cmd = 0; + + if (atoi(pinfo->reg_name_buf_nbr)>=0 && atoi(pinfo->reg_name_buf_nbr)<5) { + mode = atoi(pinfo->reg_name_buf_nbr); + } else { + mode = 0; + } + + //prec->nelm = 10; + //prec->bptr = realloc(prec->bptr, prec->nelm * dbValueSize(prec->ftvl)); + + double *pvalue = (epicsUInt32*)prec->bptr; + + pvalue[0] = (float) 3.f; + pvalue[1] = (double) 5.; + pvalue[2] = (double) 4.; + pvalue[3] = (double) 1.; + + +/* double output = -1; + for( i=0; i<( prec->nelm/2); i+=1 ){ + output = 2.;//((pdata_buf[(i*2)+1]/start)%end ) * scale; + pvalue[i] = 5.;//pdata_buf[i*2]; + pvalue[prec->nelm/2 + i] = output; + } +*/ + + cmd = 0xc1830000 + ( resolution[mode][0] << 25); + trb_register_write(0x8300,pinfo->trb_addr,25); + PadiwaSendCmd(cmd,pinfo->trb_addr,channel[mode]); + usleep(5000); + cmd = 0xd1830000 + ( resolution[mode][1] << 25); + fprintf(stderr," 1: %f \n",(double) ((( PadiwaSendCmd(cmd,pinfo->trb_addr,channel[mode])>>19)&0xfff)*multiplier[mode][0])); + usleep(5000); + cmd = 0xe1830000 + ( resolution[mode][2] << 25); + fprintf(stderr," 2: %f \n",(double) ((( PadiwaSendCmd(cmd,pinfo->trb_addr,channel[mode])>>19)&0xfff)*multiplier[mode][1]) ); + usleep(1000); + cmd = 0xf1830000 + ( resolution[mode][3] << 25); + fprintf(stderr," 3: %f \n",(double) ((( PadiwaSendCmd(cmd,pinfo->trb_addr,channel[mode])>>19)&0xfff)*multiplier[mode][2]) ); + usleep(5000); + fprintf(stderr," 4: %f \n",(double) (((PadiwaSendCmd(0xf3930000,pinfo->trb_addr,channel[mode])>>19)&0xfff)*multiplier[mode][3]) ); + usleep(5000); + fprintf(stderr," 5: %3.2f \n", (double) (((PadiwaSendCmd(0,pinfo->trb_addr,channel[mode])>>19)&0xfff)/16.)); + + trb_register_write(pinfo->trb_addr,0xd41a,7); + + } else if (search_stat == 0) { + trb_stat = trb_register_read( pinfo->trb_addr, address, pdata_buf, count ); // + if ( -1 == trb_stat ) { + /* first try failed, do it again */ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + trb_stat = trb_register_read( pinfo->trb_addr, address, pdata_buf, count ); + if ( -1 == trb_stat ) { + fprintf( stderr, "\033[31;1m%s: read_register failed: %d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + free( pdata_buf ); + if (trb_errno == 12){ + prec->nelm = prec->nelm * 2; + } + recGblSetSevr( prec, READ_ALARM, INVALID_ALARM ); + _trb_connected = false; + return -1; + } + } + if ( TRB_STATUS_WARNING == trb_errno ) { + fprintf( stderr, "%s: Warning: Status-Bit(s) have been set:\n%s\n", + prec->name, trb_termstr( trb_term ) ); +// recGblSetSevr( prec, NULL, NULL ); + return -1; + } + + if ( trb_stat != prec->nelm ) { //> + /*int trb_stat_temp = trb_stat; + trb_stat = prec->nelm; + prec->nelm = trb_stat_temp;*/ + prec->nelm = trb_stat; + prec->bptr = realloc(prec->bptr, prec->nelm * dbValueSize(prec->ftvl)); + } + + double *pvalue = (epicsUInt32*)prec->bptr; + + + //---------------------------------------------------// + double output = -1; + epicsUInt32 start = pow(2, trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].start); + epicsUInt32 end = pow(2, trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].bits); + double scale = trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].scale; + +/* for( i=0; i < trb_stat; i+=2 ) { + output = ((pdata_buf[i+1]/start)%end )*scale; + pvalue[i] = pdata_buf[i]; + pvalue[i+1] = output; + } +*/ + for( i=0; i<( prec->nelm/2); i+=1 ){ + output = ((pdata_buf[(i*2)+1]/start)%end ) * scale; + pvalue[i] = pdata_buf[i*2]; + pvalue[i+(trb_stat/2)] = output; + } + + //---------------------------------------------------// + + } else { + printf("No Address Name %s found!\n", pinfo->reg_name_buf); + } +//--------------------------------// + prec->nord = trb_stat; + + free( pdata_buf ); + + return 0; +} + diff --git a/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet2.c b/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet2.c new file mode 100644 index 0000000..8e4b4ec --- /dev/null +++ b/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet2.c @@ -0,0 +1,755 @@ +/****** I N C L U D E S *******************************************************/ + +/* ANSI C includes */ +#include +#include +#include +#include +#include + +/* EPICS includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* local includes */ +#include "trberror.h" +#include "trbnet.h" + + +#define LINELENGTH 250 + +#define NumberOfBoards 1 + +#define __Name 0 +#define __Scale 1 +#define __Unit 2 +#define __Format 3 +#define __Start 4 +#define __Bits 5 +#define __Rate 6 +#define __ErrorFlag 7 +#define __InvertFlag 8 +#define __Value 9 + +/****** D E F I N I T I O N S **************************************************/ +static long initLi( longinRecord* prec ); +static long initLo( longoutRecord* prec ); +static long initWaveform( waveformRecord* prec ); +static long processLi( longinRecord* prec ); +static long processLo( longoutRecord* prec ); +static long processWaveform( waveformRecord* prec ); + +typedef struct { + long number; + DEVSUPFUN dev_report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN process; +} dev_dset_trbnet_t; + +typedef struct { + epicsUInt16 trb_addr; + char* reg_name_buf; + epicsUInt16 reg_addr; + //char entity_name[20]; +} trbnet_info_t; + +typedef struct{ + epicsUInt16 regAddr; + char *name; + float scale; + char *unit; + char *format; + int start; + int bits; + int rate; + char *errorflag; + char *invertflag; + int value; +}field_struct; + +typedef struct{ + epicsUInt16 regAddr; + char *name; + char *purpose; + field_struct *field; + int size; + int used; + int value; +}reg_struct; + +typedef struct{ + epicsUInt16 address; + char *name; + reg_struct *Reg; + size_t size; + size_t used; +}trb_struct; + +/****** G L O B A L S **********************************************************/ +dev_dset_trbnet_t dev_trbnet_li = { 6, NULL, NULL, initLi, NULL, processLi }; +dev_dset_trbnet_t dev_trbnet_lo = { 6, NULL, NULL, initLo, NULL, processLo }; +dev_dset_trbnet_t dev_trbnet_waveform = { 6, NULL, NULL, initWaveform, NULL, processWaveform }; +trb_struct *trb; +int databaseSet = 0; + +/****** L O C A L S ************************************************************/ +static bool _trb_connected = false; + +/****** F U N C T I O N S ******************************************************/ + +epicsExportAddress( dset, dev_trbnet_li ); +epicsExportAddress( dset, dev_trbnet_lo ); +epicsExportAddress( dset, dev_trbnet_waveform ); + +/*----- TEST FUNKTION ---------------------------------------------------------*/ +int trb_register_readTESTFUNKTION( uint16_t trb_addr, + uint16_t addr, + uint32_t *data, + unsigned int dsize) +{ + int status = 0; + if (trb_addr== 0) { + if (addr== 0) { + data[0] = 0; + //data[1]=21400000; + data[1] = 557842432; + } + return 2; + } + else if(trb_addr == 1) { + data[0] = 0; + data[1] = 557842432; + data[2] = 1; + data[3] = 557845532; + data[4] = 2; + data[5] = 557823451; + data[6] = 3; + data[7] = 557733332; + data[8] = 4; + data[9] = 667823451; + data[10] = 5; + data[11] = 598733332; + return 12; + } else { + return -1; + } +} + +/*----- Necessary Functions for Database --------------------------------------*/ + +void initField(trb_struct *trb, size_t RegNumb) { + trb->Reg[RegNumb].field = (field_struct *)malloc(sizeof(field_struct)); // 1 field + trb->Reg[RegNumb].used = 0; + trb->Reg[RegNumb].size = 1; + //Init with start values + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].regAddr = trb->Reg[RegNumb].regAddr; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].name = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].scale = 1; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].unit = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].format = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].start = 0; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].bits = 32; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].rate = -1; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].errorflag = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].invertflag = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].value = -1; +} + +void initReg(trb_struct *trb, size_t initialSize) { + trb->Reg = (reg_struct *)malloc(initialSize * sizeof(reg_struct)); + trb->used = 0; + trb->size = initialSize; + int i=0; + for ( i; i < initialSize; i++) { + initField(trb, i); // trb_struct; i01= Element of Register + } +} + +// Insert a new field. Only RegAddress is Set from default +void insertField(reg_struct *reg) { + if (reg->used == reg->size) { + reg->size++; + reg->field = (field_struct *)realloc(reg->field, reg->size * sizeof(field_struct)); + } + //Init with start values + reg->field[reg->used].regAddr = reg->regAddr; //set register Address + reg->field[reg->used].name = NULL; + reg->field[reg->used].scale = 1; + reg->field[reg->used].unit = NULL; + reg->field[reg->used].format = NULL; + reg->field[reg->used].start = 0; + reg->field[reg->used].bits = 32; + reg->field[reg->used].rate = -1; + reg->field[reg->used].errorflag = NULL; + reg->field[reg->used].invertflag = NULL; + reg->field[reg->used].value = -1; + reg->used++; +} + +int setFieldPropertyInt(reg_struct *reg,int fieldNmb, int element, int data) { + if (fieldNmb < reg->used) { + if (element == __Start){ //field start + reg->field[fieldNmb].start = data; + } else if (element == __Bits){ //field bits + reg->field[fieldNmb].bits = data; + } else if (element == __Rate){ //field rate + reg->field[fieldNmb].rate = data; + } else if (element == __Value){ //field ratevalue + reg->field[fieldNmb].value = data; + } else { + printf("Element does not Fit to a INT Type property.\n"); + } + return 0; + } else { + return 1; //Error + } +} + +int setFieldPropertyStr(reg_struct *reg,int fieldNmb, int element, char *data) { + if (fieldNmb < reg->used) { + if(element == __Name){ //field NAME + reg->field[fieldNmb].name =strdup(data); + } else if (element == __Unit){ //field UNIT + reg->field[fieldNmb].unit = strdup(data); + } else if (element == __Format){ //field format + reg->field[fieldNmb].format = strdup(data); + } else if (element == __ErrorFlag){ //field errorflag + reg->field[fieldNmb].errorflag = strdup(data); + } else if (element == __InvertFlag){//field invertflag + reg->field[fieldNmb].invertflag = strdup(data); + } else { + printf("Element does not Fit to a STRING Type property.\n"); + } + return 0; + } else { + return 1; //Error; Field does not exist + } +} + +int setFieldPropertyFloat(reg_struct *reg, int fieldNmb, int element, float data) { + if (fieldNmb < reg->used) { + if (element == __Scale){ //field SCALE + reg->field[fieldNmb].scale = data; + } else { + printf("Element does not Fit to a FLOAT Type property.\n"); + } + return 0; + } else { + return 1; //Error; Field does not exist + } +} + +void insertReg(trb_struct *trb, int element) { + if (trb->used == trb->size) { + trb->size++; + trb->Reg = (reg_struct *)realloc(trb->Reg, trb->size * sizeof(reg_struct)); + } + trb->Reg[trb->used].regAddr = element; + initField(trb, trb->used); + trb->used++; +} + +// free the allocated memory of the fields of each Register +void freeField(trb_struct *trb) { + int i=0; + for (i;iused;i++){ + free(trb->Reg[i].field); + trb->Reg[i].field = NULL; + trb->Reg[i].used = trb->Reg[i].size = 0; + } +} + +// free the allocated memory of each register +void freeReg(trb_struct *trb) { + freeField(trb); + free(trb->Reg); + trb->Reg = NULL; + trb->used = trb->size = 0; +} + +/*----- Common initialization for all records ---------------------------------*/ + +static long initCommon( dbCommon* prec, DBLINK* plink ) { + + trbnet_info_t *pinfo; + char entity_name_buf[20] = ""; + char Reg_name_buf[20] = ""; + epicsUInt32 trb_addr_buf = 0; + epicsUInt32 reg_addr_buf = 0; + + char linebuffer[LINELENGTH]; + + if ( sscanf( plink->value.instio.string, "%s %x %s", entity_name_buf, &trb_addr_buf, Reg_name_buf ) != 3 ) { + fprintf( stderr, "\033[31;1m%s: Invalid value of INP/OUT field '%s'\033[0m\n", + prec->name, plink->value.instio.string ); + return -1; + } + if ( 0xffff < trb_addr_buf ) { + fprintf( stderr, "\033[31;1m%s: Invalid trb address '%x'\033[0m\n", + prec->name, trb_addr_buf ); + return -1; + } + + + pinfo = callocMustSucceed( 1, sizeof(*pinfo), "devTrbnet::initCommon" ); + pinfo->trb_addr = (epicsUInt16)( trb_addr_buf & 0xffff ); + pinfo->reg_name_buf = strdup(Reg_name_buf); + prec->dpvt = pinfo; + prec->udf = FALSE; + int i=0; + + + +// create Memory for each TrbBoard + if (databaseSet==0) + { + trb = (trb_struct *) malloc(NumberOfBoards * sizeof(trb_struct)); + + for(i=0;i") == 0){ + group_open = false; + } + if (strcmp(node,"") == 0){ + register_open = false; + } + if (strcmp(node,"") == 0){ + field_open = false; + } + + // analyse each part of one line of .xml document + while(ptr != NULL) { + + if (group_open==true && register_open==false && field_open==false) { + sscanf(ptr, "address=\"%x\"", &gaddress); + sscanf(ptr, "name=\"%[A-z,_0-9]\"", gname); + sscanf(ptr, "mode=\"%[A-z,_,0-9]\"", gmode); + } + if (register_open==true && group_open==true && field_open==false){ + if(sscanf(ptr, "address=\"%x\"", ®_addr_buf)==1){ + pinfo->reg_addr = (epicsUInt16)( (reg_addr_buf + gaddress) & 0xffff ); + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].regAddr = pinfo->reg_addr; + } + } + if(sscanf(ptr, "name=\"%[A-z,_0-9]\"", rname)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].name = strdup(rname); + } + } + + if(sscanf(ptr, "purpose=\"%[A-z,_0-9]\"", purpose)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].purpose = strdup(purpose); + } + } + } + + if (field_open==true && group_open==true && register_open==true){ + if (strcmp(ptr,"/>\n") == 0){ + field_open=false; + } + if (sscanf(ptr, "name=\"%[A-z,_0-9]\"", fname)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].name = strdup(fname); + } + } + if (sscanf(ptr, "format=\"%[A-z,_0-9]\"", fformat)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].format = strdup(fformat); + } + } + if (sscanf(ptr, "bits=%*c%i%*c", &bits)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].bits = bits; + } + } + if (sscanf(ptr, "start=%*c%i%*c", &start)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].start = start; + } + } + if (sscanf(ptr, "rate=%*c%i%*c", &rate )==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].rate = rate; + } + } + if (sscanf(ptr, "unit=%*c%x%*c", &unit )==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].unit = unit; + } + } + if (sscanf(ptr, "scale=%*c%f%*c", &scale )==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].scale = scale; + } + } + } + + ptr = strtok(NULL, delimiter); + }//end while2 + }//end while1 + fclose(fp); + databaseSet = 1; + } + if ( 0xffff < reg_addr_buf ) { + fprintf( stderr, "\033[31;1m%s: Invalid register address '%x'\033[0m\n",prec->name, reg_addr_buf ); + return -1; + } + +//----------------------------------------------------------------------// + + // Test the fields + printf("Register Addres: %i\n", trb[0].Reg[8].regAddr); // getAddr of Register[0] + printf("Number of registers: %i\n", trb[0].size); // print number of fields in Register + printf("Number of fields:%i\n", trb[0].Reg[0].size); // print name of field 1 in Register 0 + printf("Number of fields:%s\n", trb[0].Reg[1].field[0].name); // print name of field 1 in Register 0 + printf("%i\n", trb[0].used); // getAddr of Register[0] + +//---------------------------------------------------------------------------------------------// + /*free memory + for(i=0;ipact = (epicsUInt8)true; /* disable record */ + + status = initCommon( (dbCommon *)prec, &prec->inp ); + prec->pact = (epicsUInt8)false; /* enable record */ + + return status; +} + +/*----- initialization of longout records -------------------------------------*/ +static long initLo( longoutRecord* prec ) { + long status = 0; + prec->pact = (epicsUInt8)true; /* disable record */ + + status = initCommon( (dbCommon *)prec, &prec->out ); + prec->pact = (epicsUInt8)false; /* enable record */ + + return status; +} + +/*----- initialization of waveform records ------------------------------------*/ +static long initWaveform( waveformRecord* prec ) { + long status = 0; + prec->pact = (epicsUInt8)true; /* disable record */ + + if ( DBF_DOUBLE != prec->ftvl ) { + fprintf( stderr, "\033[31;1m%s: Invalid field type of value\033[0m\n", prec->name ); + return -1; + } + + status = initCommon( (dbCommon *)prec, &prec->inp ); + prec->pact = (epicsUInt8)false; /* enable record */ + + return status; +} + +/*----- process routine of longin records -------------------------------------*/ +static long processLi( longinRecord* prec ) { + trbnet_info_t* pinfo = (trbnet_info_t*)prec->dpvt; + epicsUInt32 data[2] = { 0 }; + int trb_stat = 0; + + int j,k,i,address; + int search_stat = 0 ; + int trb_Nmb=0, reg_Nmb=0, field_Nmb=0; + + if( !_trb_connected ){ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); // could be a problem (prec->name) + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + _trb_connected = true; + } + + // READ Address from Database + for(i=0;ireg_name_buf) == 0){ + search_stat = 0; + } + else { + for(k=0;kreg_name_buf) == 0){ + address = trb[i].Reg[j].field[k].regAddr; + search_stat = 0; + trb_Nmb=i; reg_Nmb=j; field_Nmb=k; + } else { + search_stat = -1; + } + } + } + } + } + + if (search_stat){ + int data_size = 2; + //trb_stat = trb_register_read( pinfo->trb_addr, address, data, data_size ); + //trb_stat = trb_register_readTESTFUNKTION( pinfo->trb_addr, address, data, data_size ); + + //--------------------------------------// + if ( -1 == trb_stat ) { + /* first try failed, do it again */ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + trb_stat = trb_register_read( pinfo->trb_addr, address, data, data_size ); + if ( -1 == trb_stat ) { + /* second try failed, return error */ + fprintf( stderr, "\033[31;1m%s: read_register failed: %d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, READ_ALARM, INVALID_ALARM ); + _trb_connected = false; + return -1; + } + } + /* Check Status-Bits */ + if ( TRB_STATUS_WARNING == trb_errno ) { + fprintf( stderr, "%s: Warning: Status-Bit(s) have been set:\n%s\n", + prec->name, trb_termstr( trb_term ) ); + return -1; + } + //------------------------------// + double output = -1; + epicsUInt32 start = pow(2, trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].start); + epicsUInt32 end = pow(2, trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].bits); + double scale = trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].scale; + + for (i=0; i< data_size;i+=2){ + output = ((data[i+1]/start)%end )*scale; + prec->val = output; + } + //--------------------------------// + + } else { + printf("No Address Name %s found!\n", pinfo->reg_name_buf); + } + + + return 0; +} + +//----- LONGOUT IS NOT IN USE!!!-----------------------------------------------// +/*----- process routine of longout records ------------------------------------*/ +static long processLo( longoutRecord* prec ) { + trbnet_info_t* pinfo = (trbnet_info_t*)prec->dpvt; + epicsUInt32 value = prec->val; + int trb_stat = 0; + + if( !_trb_connected ) { + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + _trb_connected = true; + } + + trb_stat = trb_register_write( pinfo->trb_addr, pinfo->reg_addr, value ); + if ( -1 == trb_stat ) { + /* first try failed, do it again */ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + trb_stat = trb_register_write( pinfo->trb_addr, pinfo->reg_addr, value ); + if ( -1 == trb_stat ) { + /* second try failed, return error */ + fprintf( stderr, "\033[31;1m%s: write_register failed: %d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, WRITE_ALARM, INVALID_ALARM ); + _trb_connected = false; + return -1; + } + } + if ( TRB_STATUS_WARNING == trb_errno ) { + fprintf( stderr, "%s: Warning: Status-Bit(s) have been set:\n%s\n", + prec->name, trb_termstr( trb_term ) ); + return -1; + } + + return 0; +} + +/*----- process routine of waveform records -----------------------------------*/ +static long processWaveform( waveformRecord* prec ) { + trbnet_info_t *pinfo = (trbnet_info_t*)prec->dpvt; + double *pvalue = (epicsUInt32*)prec->bptr; + epicsUInt32 *pdata_buf; + epicsUInt32 count = 200;//prec->nelm; // equal to 100 boards + int trb_stat = 0; + int i = 0; + + + if( !_trb_connected ) { + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); // same as above + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + _trb_connected = true; + } + + pdata_buf = callocMustSucceed( count, sizeof(epicsUInt32), "devTrbnet::processWaveform" ); + + int j,k,address; + int search_stat = 0 ; + int trb_Nmb=0, reg_Nmb=0, field_Nmb=0; + + for(i=0;ireg_name_buf) == 0){ + search_stat = 0; + } + else { + for(k=0;kreg_name_buf) == 0){ + address = trb[i].Reg[j].field[k].regAddr; + search_stat = 0; + trb_Nmb=i; reg_Nmb=j; field_Nmb=k; + } else { + search_stat = -1; + } + } + } + } + } + int data_size = 2; + if (search_stat){ + + //trb_stat = trb_register_readTESTFUNKTION( pinfo->trb_addr, address, pdata_buf, count ); + + trb_stat = trb_register_read( pinfo->trb_addr, address, pdata_buf, count ); + if ( -1 == trb_stat ) { + /* first try failed, do it again */ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + trb_stat = trb_register_read( pinfo->trb_addr, address, pdata_buf, count ); + if ( -1 == trb_stat ) { + fprintf( stderr, "\033[31;1m%s: read_register failed: %d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + free( pdata_buf ); + recGblSetSevr( prec, READ_ALARM, INVALID_ALARM ); + _trb_connected = false; + return -1; + } + } + if ( TRB_STATUS_WARNING == trb_errno ) { + fprintf( stderr, "%s: Warning: Status-Bit(s) have been set:\n%s\n", + prec->name, trb_termstr( trb_term ) ); + return -1; + } + + if ( trb_stat > prec->nelm ) { + int trb_stat_temp = trb_stat; + trb_stat = prec->nelm; + prec->nelm = trb_stat_temp; + } + + //---------------------------------------------------// + double output = -1; + epicsUInt32 start = pow(2, trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].start); + epicsUInt32 end = pow(2, trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].bits); + double scale = trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].scale; + + for( i=0; i < trb_stat; i+=2 ) { + output = ((pdata_buf[i+1]/start)%end )*scale; + pvalue[i] = pdata_buf[i]; + pvalue[i+1] = output; + } + + //---------------------------------------------------// + + } else { + printf("No Address Name %s found!\n", pinfo->reg_name_buf); + } +//--------------------------------// + prec->nord = trb_stat; + + free( pdata_buf ); + + return 0; +} + diff --git a/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet3.c b/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet3.c new file mode 100644 index 0000000..a19a2e2 --- /dev/null +++ b/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet3.c @@ -0,0 +1,302 @@ +/******************************************************************************* + * Copyright (C) 2013 Florian Feldbauer + * - Helmholtz-Institut Mainz + * + * This file is part of devTrbnet + * + * devTrbnet is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * devTrbnet is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + ******************************************************************************/ + +/****** I N C L U D E S *******************************************************/ + +/* ANSI C includes */ +#include +#include +#include + +/* EPICS includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* local includes */ +#include "trberror.h" +#include "trbnet.h" + +/****** D E F I N I T I O N S **************************************************/ +static long initLi( longinRecord* prec ); +static long initLo( longoutRecord* prec ); +static long initWaveform( waveformRecord* prec ); +static long processLi( longinRecord* prec ); +static long processLo( longoutRecord* prec ); +static long processWaveform( waveformRecord* prec ); + +typedef struct { + long number; + DEVSUPFUN dev_report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN process; +} dev_dset_trbnet_t; + +typedef struct { + epicsUInt16 trb_addr; + epicsUInt16 reg_addr; +} trbnet_info_t; + +/****** G L O B A L S **********************************************************/ +dev_dset_trbnet_t dev_trbnet_li = { 6, NULL, NULL, initLi, NULL, processLi }; +dev_dset_trbnet_t dev_trbnet_lo = { 6, NULL, NULL, initLo, NULL, processLo }; +dev_dset_trbnet_t dev_trbnet_waveform = { 6, NULL, NULL, initWaveform, NULL, processWaveform }; + +/****** L O C A L S ************************************************************/ +static bool _trb_connected = false; + +/****** F U N C T I O N S ******************************************************/ + +epicsExportAddress( dset, dev_trbnet_li ); +epicsExportAddress( dset, dev_trbnet_lo ); +epicsExportAddress( dset, dev_trbnet_waveform ); + +/*----- Common initialization for all records ---------------------------------*/ +static long initCommon( dbCommon* prec, DBLINK* plink ) { + + trbnet_info_t *pinfo; + epicsUInt32 trb_addr_buf = 0; + epicsUInt32 reg_addr_buf = 0; + + if ( sscanf( plink->value.instio.string, "%x %x", &trb_addr_buf, ®_addr_buf ) != 2 ) { + fprintf( stderr, "\033[31;1m%s: Invalid value of INP/OUT field '%s'\033[0m\n", + prec->name, plink->value.instio.string ); + return -1; + } + if ( 0xffff < trb_addr_buf ) { + fprintf( stderr, "\033[31;1m%s: Invalid trb address '%x'\033[0m\n", + prec->name, trb_addr_buf ); + return -1; + } + if ( 0xffff < reg_addr_buf ) { + fprintf( stderr, "\033[31;1m%s: Invalid register address '%x'\033[0m\n", + prec->name, reg_addr_buf ); + return -1; + } + + pinfo = callocMustSucceed( 1, sizeof(*pinfo), "devTrbnet::initCommon" ); + pinfo->trb_addr = (epicsUInt16)( trb_addr_buf & 0xffff ); + pinfo->reg_addr = (epicsUInt16)( reg_addr_buf & 0xffff ); + + prec->dpvt = pinfo; + prec->udf = FALSE; + + return 0; +} + +/*----- initialization of longin records --------------------------------------*/ +static long initLi( longinRecord* prec ) { + long status = 0; + prec->pact = (epicsUInt8)true; /* disable record */ + + status = initCommon( (dbCommon *)prec, &prec->inp ); + prec->pact = (epicsUInt8)false; /* enable record */ + + return status; +} + +/*----- initialization of longout records -------------------------------------*/ +static long initLo( longoutRecord* prec ) { + long status = 0; + prec->pact = (epicsUInt8)true; /* disable record */ + + status = initCommon( (dbCommon *)prec, &prec->out ); + prec->pact = (epicsUInt8)false; /* enable record */ + + return status; +} + +/*----- initialization of waveform records ------------------------------------*/ +static long initWaveform( waveformRecord* prec ) { + long status = 0; + prec->pact = (epicsUInt8)true; /* disable record */ + + if ( DBF_ULONG != prec->ftvl ) { + fprintf( stderr, "\033[31;1m%s: Invalid field type of value\033[0m\n", prec->name ); + return -1; + } + + status = initCommon( (dbCommon *)prec, &prec->inp ); + prec->pact = (epicsUInt8)false; /* enable record */ + + return status; +} + +/*----- process routine of longin records -------------------------------------*/ +static long processLi( longinRecord* prec ) { + trbnet_info_t* pinfo = (trbnet_info_t*)prec->dpvt; + epicsUInt32 data[2] = { 0 }; + int trb_stat = 0; + + if( !_trb_connected ){ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: Nr1 init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + _trb_connected = true; + } + + trb_stat = trb_register_read( pinfo->trb_addr, pinfo->reg_addr, data, 2 ); + if ( -1 == trb_stat ) { + /* first try failed, do it again */ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: Nr2 init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + trb_stat = trb_register_read( pinfo->trb_addr, pinfo->reg_addr, data, 2 ); + if ( -1 == trb_stat ) { + /* second try failed, return error */ + fprintf( stderr, "\033[31;1m%s: read_register failed: %d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, READ_ALARM, INVALID_ALARM ); + _trb_connected = false; + return -1; + } + } + /* Check Status-Bits */ + if ( TRB_STATUS_WARNING == trb_errno ) { + fprintf( stderr, "%s: Warning: Status-Bit(s) have been set:\n%s\n", + prec->name, trb_termstr( trb_term ) ); + return -1; + } + + prec->val = data[1]; + return 0; +} + +/*----- process routine of longout records ------------------------------------*/ +static long processLo( longoutRecord* prec ) { + trbnet_info_t* pinfo = (trbnet_info_t*)prec->dpvt; + epicsUInt32 value = prec->val; + int trb_stat = 0; + + if( !_trb_connected ) { + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + _trb_connected = true; + } + + trb_stat = trb_register_write( pinfo->trb_addr, pinfo->reg_addr, value ); + if ( -1 == trb_stat ) { + /* first try failed, do it again */ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + trb_stat = trb_register_write( pinfo->trb_addr, pinfo->reg_addr, value ); + if ( -1 == trb_stat ) { + /* second try failed, return error */ + fprintf( stderr, "\033[31;1m%s: write_register failed: %d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, WRITE_ALARM, INVALID_ALARM ); + _trb_connected = false; + return -1; + } + } + if ( TRB_STATUS_WARNING == trb_errno ) { + fprintf( stderr, "%s: Warning: Status-Bit(s) have been set:\n%s\n", + prec->name, trb_termstr( trb_term ) ); + return -1; + } + + return 0; +} + +/*----- process routine of waveform records -----------------------------------*/ +static long processWaveform( waveformRecord* prec ) { + trbnet_info_t *pinfo = (trbnet_info_t*)prec->dpvt; + epicsUInt32 *pvalue = (epicsUInt32*)prec->bptr; + epicsUInt32 *pdata_buf; + epicsUInt32 count = prec->nelm; + int trb_stat = 0; + int i = 0; + + if( !_trb_connected ) { + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + _trb_connected = true; + } + + pdata_buf = callocMustSucceed( count, sizeof(epicsUInt32), "devTrbnet::processWaveform" ); + + trb_stat = trb_register_read( pinfo->trb_addr, pinfo->reg_addr, pdata_buf, count ); + if ( -1 == trb_stat ) { + /* first try failed, do it again */ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + trb_stat = trb_register_read( pinfo->trb_addr, pinfo->reg_addr, pdata_buf, count ); + if ( -1 == trb_stat ) { + fprintf( stderr, "\033[31;1m%s: read_register failed: %d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + free( pdata_buf ); + recGblSetSevr( prec, READ_ALARM, INVALID_ALARM ); + _trb_connected = false; + return -1; + } + } + if ( TRB_STATUS_WARNING == trb_errno ) { + fprintf( stderr, "%s: Warning: Status-Bit(s) have been set:\n%s\n", + prec->name, trb_termstr( trb_term ) ); + return -1; + } + + if ( trb_stat > prec->nelm ) trb_stat = prec->nelm; + for( ; i < trb_stat; i++ ) pvalue[i] = pdata_buf[i]; + + prec->nord = trb_stat; + + free( pdata_buf ); + return 0; +} + diff --git a/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet_save.c b/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet_save.c new file mode 100644 index 0000000..e6ce923 --- /dev/null +++ b/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet_save.c @@ -0,0 +1,769 @@ +/****** I N C L U D E S *******************************************************/ + +/* ANSI C includes */ +#include +#include +#include +#include +#include + +/* EPICS includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* local includes */ +#include "trberror.h" +#include "trbnet.h" + + +#define LINELENGTH 250 + +#define NumberOfBoards 1 + +#define __Name 0 +#define __Scale 1 +#define __Unit 2 +#define __Format 3 +#define __Start 4 +#define __Bits 5 +#define __Rate 6 +#define __ErrorFlag 7 +#define __InvertFlag 8 +#define __Value 9 + +/****** D E F I N I T I O N S **************************************************/ +static long initLi( longinRecord* prec ); +static long initLo( longoutRecord* prec ); +static long initWaveform( waveformRecord* prec ); +static long processLi( longinRecord* prec ); +static long processLo( longoutRecord* prec ); +static long processWaveform( waveformRecord* prec ); + +typedef struct { + long number; + DEVSUPFUN dev_report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN process; +} dev_dset_trbnet_t; + +typedef struct { + epicsUInt16 trb_addr; + char* reg_name_buf; + epicsUInt16 reg_addr; + //char entity_name[20]; +} trbnet_info_t; + +typedef struct{ + epicsUInt16 regAddr; + char *name; + float scale; + char *unit; + char *format; + int start; + int bits; + int rate; + char *errorflag; + char *invertflag; + int value; +}field_struct; + +typedef struct{ + epicsUInt16 regAddr; + char *name; + char *purpose; + field_struct *field; + int size; + int used; + int value; +}reg_struct; + +typedef struct{ + epicsUInt16 address; + char *name; + reg_struct *Reg; + size_t size; + size_t used; +}trb_struct; + +/****** G L O B A L S **********************************************************/ +dev_dset_trbnet_t dev_trbnet_li = { 6, NULL, NULL, initLi, NULL, processLi }; +dev_dset_trbnet_t dev_trbnet_lo = { 6, NULL, NULL, initLo, NULL, processLo }; +dev_dset_trbnet_t dev_trbnet_waveform = { 6, NULL, NULL, initWaveform, NULL, processWaveform }; +trb_struct *trb; +int databaseSet = 0; + +/****** L O C A L S ************************************************************/ +static bool _trb_connected = false; + +/****** F U N C T I O N S ******************************************************/ + +epicsExportAddress( dset, dev_trbnet_li ); +epicsExportAddress( dset, dev_trbnet_lo ); +epicsExportAddress( dset, dev_trbnet_waveform ); + +/*----- TEST FUNKTION ---------------------------------------------------------*/ +int trb_register_readTESTFUNKTION( uint16_t trb_addr, + uint16_t addr, + uint32_t *data, + unsigned int dsize) +{ + int status = 0; + if (trb_addr== 0) { + if (addr== 0) { + data[0] = 0; + //data[1]=21400000; + data[1] = 557842432; + } + return 2; + } + else if(trb_addr == 1) { + data[0] = 0; + data[1] = 557842432; + data[2] = 1; + data[3] = 557845532; + data[4] = 2; + data[5] = 557823451; + data[6] = 3; + data[7] = 557733332; + data[8] = 4; + data[9] = 667823451; + data[10] = 5; + data[11] = 598733332; + return 12; + } else { + return -1; + } +} + +/*----- Necessary Functions for Database --------------------------------------*/ + +void initField(trb_struct *trb, size_t RegNumb) { + trb->Reg[RegNumb].field = (field_struct *)malloc(sizeof(field_struct)); // 1 field + trb->Reg[RegNumb].used = 0; + trb->Reg[RegNumb].size = 1; + //Init with start values + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].regAddr = trb->Reg[RegNumb].regAddr; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].name = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].scale = 1; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].unit = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].format = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].start = 0; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].bits = 32; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].rate = -1; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].errorflag = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].invertflag = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].value = -1; +} + +void initReg(trb_struct *trb, size_t initialSize) { + trb->Reg = (reg_struct *)malloc(initialSize * sizeof(reg_struct)); + trb->used = 0; + trb->size = initialSize; + int i=0; + for ( i; i < initialSize; i++) { + initField(trb, i); // trb_struct; i01= Element of Register + } +} + +// Insert a new field. Only RegAddress is Set from default +void insertField(reg_struct *reg) { + if (reg->used == reg->size) { + reg->size++; + reg->field = (field_struct *)realloc(reg->field, reg->size * sizeof(field_struct)); + } + //Init with start values + reg->field[reg->used].regAddr = reg->regAddr; //set register Address + reg->field[reg->used].name = NULL; + reg->field[reg->used].scale = 1; + reg->field[reg->used].unit = NULL; + reg->field[reg->used].format = NULL; + reg->field[reg->used].start = 0; + reg->field[reg->used].bits = 32; + reg->field[reg->used].rate = -1; + reg->field[reg->used].errorflag = NULL; + reg->field[reg->used].invertflag = NULL; + reg->field[reg->used].value = -1; + reg->used++; +} + +int setFieldPropertyInt(reg_struct *reg,int fieldNmb, int element, int data) { + if (fieldNmb < reg->used) { + if (element == __Start){ //field start + reg->field[fieldNmb].start = data; + } else if (element == __Bits){ //field bits + reg->field[fieldNmb].bits = data; + } else if (element == __Rate){ //field rate + reg->field[fieldNmb].rate = data; + } else if (element == __Value){ //field ratevalue + reg->field[fieldNmb].value = data; + } else { + printf("Element does not Fit to a INT Type property.\n"); + } + return 0; + } else { + return 1; //Error + } +} + +int setFieldPropertyStr(reg_struct *reg,int fieldNmb, int element, char *data) { + if (fieldNmb < reg->used) { + if(element == __Name){ //field NAME + reg->field[fieldNmb].name =strdup(data); + } else if (element == __Unit){ //field UNIT + reg->field[fieldNmb].unit = strdup(data); + } else if (element == __Format){ //field format + reg->field[fieldNmb].format = strdup(data); + } else if (element == __ErrorFlag){ //field errorflag + reg->field[fieldNmb].errorflag = strdup(data); + } else if (element == __InvertFlag){//field invertflag + reg->field[fieldNmb].invertflag = strdup(data); + } else { + printf("Element does not Fit to a STRING Type property.\n"); + } + return 0; + } else { + return 1; //Error; Field does not exist + } +} + +int setFieldPropertyFloat(reg_struct *reg, int fieldNmb, int element, float data) { + if (fieldNmb < reg->used) { + if (element == __Scale){ //field SCALE + reg->field[fieldNmb].scale = data; + } else { + printf("Element does not Fit to a FLOAT Type property.\n"); + } + return 0; + } else { + return 1; //Error; Field does not exist + } +} + +void insertReg(trb_struct *trb, int element) { + if (trb->used == trb->size) { + trb->size++; + trb->Reg = (reg_struct *)realloc(trb->Reg, trb->size * sizeof(reg_struct)); + } + trb->Reg[trb->used].regAddr = element; + initField(trb, trb->used); + trb->used++; +} + +// free the allocated memory of the fields of each Register +void freeField(trb_struct *trb) { + int i=0; + for (i;iused;i++){ + free(trb->Reg[i].field); + trb->Reg[i].field = NULL; + trb->Reg[i].used = trb->Reg[i].size = 0; + } +} + +// free the allocated memory of each register +void freeReg(trb_struct *trb) { + freeField(trb); + free(trb->Reg); + trb->Reg = NULL; + trb->used = trb->size = 0; +} + +/*----- Common initialization for all records ---------------------------------*/ + +static long initCommon( dbCommon* prec, DBLINK* plink ) { + + trbnet_info_t *pinfo; + char entity_name_buf[20] = ""; + char Reg_name_buf[20] = ""; + epicsUInt32 trb_addr_buf = 0; + epicsUInt32 reg_addr_buf = 0; + + char linebuffer[LINELENGTH]; + + if ( sscanf( plink->value.instio.string, "%s %x %s", entity_name_buf, &trb_addr_buf, Reg_name_buf ) != 3 ) { + fprintf( stderr, "\033[31;1m%s: Invalid value of INP/OUT field '%s'\033[0m\n", + prec->name, plink->value.instio.string ); + return -1; + } + if ( 0xffff < trb_addr_buf ) { + fprintf( stderr, "\033[31;1m%s: Invalid trb address '%x'\033[0m\n", + prec->name, trb_addr_buf ); + return -1; + } + + + pinfo = callocMustSucceed( 1, sizeof(*pinfo), "devTrbnet::initCommon" ); + pinfo->trb_addr = (epicsUInt16)( trb_addr_buf & 0xffff ); + pinfo->reg_name_buf = strdup(Reg_name_buf); + prec->dpvt = pinfo; + prec->udf = FALSE; + int i=0; + + + +// create Memory for each TrbBoard + if (databaseSet==0) + { + trb = (trb_struct *) malloc(NumberOfBoards * sizeof(trb_struct)); + + for(i=0;i") == 0){ + group_open = false; + } + if (strcmp(node,"") == 0){ + register_open = false; + } + if (strcmp(node,"") == 0){ + field_open = false; + } + + // analyse each part of one line of .xml document + while(ptr != NULL) { + + if (group_open==true && register_open==false && field_open==false) { + sscanf(ptr, "address=\"%x\"", &gaddress); + sscanf(ptr, "name=\"%[A-z,_0-9]\"", gname); + sscanf(ptr, "mode=\"%[A-z,_,0-9]\"", gmode); + } + if (register_open==true && group_open==true && field_open==false){ + if(sscanf(ptr, "address=\"%x\"", ®_addr_buf)==1){ + pinfo->reg_addr = (epicsUInt16)( (reg_addr_buf + gaddress) & 0xffff ); + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].regAddr = pinfo->reg_addr; + } + } + if(sscanf(ptr, "name=\"%[A-z,_0-9]\"", rname)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].name = strdup(rname); + } + } + + if(sscanf(ptr, "purpose=\"%[A-z,_0-9]\"", purpose)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].purpose = strdup(purpose); + } + } + } + + if (field_open==true && group_open==true && register_open==true){ + if (strcmp(ptr,"/>\n") == 0){ + field_open=false; + } + if (sscanf(ptr, "name=\"%[A-z,_0-9]\"", fname)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].name = strdup(fname); + } + } + if (sscanf(ptr, "format=\"%[A-z,_0-9]\"", fformat)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].format = strdup(fformat); + } + } + if (sscanf(ptr, "bits=%*c%i%*c", &bits)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].bits = bits; + } + } + if (sscanf(ptr, "start=%*c%i%*c", &start)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].start = start; + } + } + if (sscanf(ptr, "rate=%*c%i%*c", &rate )==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].rate = rate; + } + } + if (sscanf(ptr, "unit=%*c%x%*c", &unit )==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].unit = unit; + } + } + if (sscanf(ptr, "scale=%*c%f%*c", &scale )==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].scale = scale; + } + } + } + + ptr = strtok(NULL, delimiter); + }//end while2 + }//end while1 + + fclose(fp); + databaseSet = 1; + } + if ( 0xffff < reg_addr_buf ) { + fprintf( stderr, "\033[31;1m%s: Invalid register address '%x'\033[0m\n",prec->name, reg_addr_buf ); + return -1; + } + +//----------------------------------------------------------------------// + +/* // Test the fields + printf("Register Addres: %i\n", trb[0].Reg[8].regAddr); // getAddr of Register[0] + printf("Number of registers: %i\n", trb[0].size); // print number of fields in Register + printf("Number of fields:%i\n", trb[0].Reg[0].size); // print name of field 1 in Register 0 + printf("Number of fields:%s\n", trb[0].Reg[1].field[0].name); // print name of field 1 in Register 0 + printf("%i\n", trb[0].used); // getAddr of Register[0] +*/ +//---------------------------------------------------------------------------------------------// + /*free memory + for(i=0;ipact = (epicsUInt8)true; /* disable record */ + + status = initCommon( (dbCommon *)prec, &prec->inp ); + prec->pact = (epicsUInt8)false; /* enable record */ + + return status; +} + +/*----- initialization of longout records -------------------------------------*/ +static long initLo( longoutRecord* prec ) { + long status = 0; + prec->pact = (epicsUInt8)true; /* disable record */ + + status = initCommon( (dbCommon *)prec, &prec->out ); + prec->pact = (epicsUInt8)false; /* enable record */ + + return status; +} + +/*----- initialization of waveform records ------------------------------------*/ +static long initWaveform( waveformRecord* prec ) { + long status = 0; + prec->pact = (epicsUInt8)true; /* disable record */ + + if ( DBF_DOUBLE != prec->ftvl ) { + fprintf( stderr, "\033[31;1m%s: Invalid field type of value\033[0m\n", prec->name ); + return -1; + } + + status = initCommon( (dbCommon *)prec, &prec->inp ); + prec->pact = (epicsUInt8)false; /* enable record */ + + return status; +} + +/*----- process routine of longin records -------------------------------------*/ +static long processLi( longinRecord* prec ) { + trbnet_info_t* pinfo = (trbnet_info_t*)prec->dpvt; + epicsUInt32 data[2] = { 0 }; + int trb_stat = 0; + + int j,k,i,address; + int search_stat = 0 ; + int trb_Nmb=0, reg_Nmb=0, field_Nmb=0; + + if( !_trb_connected ){ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); // could be a problem (prec->name) + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + _trb_connected = true; + } + + // READ Address from Database + for(i=0;ireg_name_buf) == 0){ + search_stat = 0; + } + else { + for(k=0;kreg_name_buf) == 0){ + address = trb[i].Reg[j].field[k].regAddr; + search_stat = 0; + trb_Nmb=i; reg_Nmb=j; field_Nmb=k; + } else { + search_stat = -1; + } + } + } + } + } + + if (search_stat){ + int data_size = 2; + trb_stat = trb_register_read( pinfo->trb_addr, address, data, data_size ); + //trb_stat = trb_register_readTESTFUNKTION( pinfo->trb_addr, address, data, data_size ); + + //--------------------------------------// + if ( -1 == trb_stat ) { + /* first try failed, do it again */ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + trb_stat = trb_register_read( pinfo->trb_addr, address, data, data_size ); + if ( -1 == trb_stat ) { + /* second try failed, return error */ + fprintf( stderr, "\033[31;1m%s: read_register failed: %d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, READ_ALARM, INVALID_ALARM ); + _trb_connected = false; + return -1; + } + } + /* Check Status-Bits */ + if ( TRB_STATUS_WARNING == trb_errno ) { + fprintf( stderr, "%s: Warning: Status-Bit(s) have been set:\n%s\n", + prec->name, trb_termstr( trb_term ) ); + recGblSetSevr( prec, NULL, NULL); + return -1; + } + //------------------------------// + double output = -1; + epicsUInt32 start = pow(2, trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].start); + epicsUInt32 end = pow(2, trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].bits); + double scale = trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].scale; + + for (i=0; i< data_size;i+=2){ + output = ((data[i+1]/start)%end )*scale; + prec->val = output; + } + //--------------------------------// + + } else { + printf("No Address Name %s found!\n", pinfo->reg_name_buf); + } + + + return 0; +} + +//----- LONGOUT IS NOT IN USE!!!-----------------------------------------------// +/*----- process routine of longout records ------------------------------------*/ +static long processLo( longoutRecord* prec ) { + trbnet_info_t* pinfo = (trbnet_info_t*)prec->dpvt; + epicsUInt32 value = prec->val; + int trb_stat = 0; + + if( !_trb_connected ) { + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + _trb_connected = true; + } + + trb_stat = trb_register_write( pinfo->trb_addr, pinfo->reg_addr, value ); + if ( -1 == trb_stat ) { + /* first try failed, do it again */ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + trb_stat = trb_register_write( pinfo->trb_addr, pinfo->reg_addr, value ); + if ( -1 == trb_stat ) { + /* second try failed, return error */ + fprintf( stderr, "\033[31;1m%s: write_register failed: %d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, WRITE_ALARM, INVALID_ALARM ); + _trb_connected = false; + return -1; + } + } + if ( TRB_STATUS_WARNING == trb_errno ) { + fprintf( stderr, "%s: Warning: Status-Bit(s) have been set:\n%s\n", + prec->name, trb_termstr( trb_term ) ); + return -1; + } + + return 0; +} + +/*----- process routine of waveform records -----------------------------------*/ +static long processWaveform( waveformRecord* prec ) { + trbnet_info_t *pinfo = (trbnet_info_t*)prec->dpvt; + epicsUInt32 *pdata_buf; + epicsUInt32 count = 200;//prec->nelm; // equal to 100 boards + int trb_stat = 0; + int i = 0; + + + if( !_trb_connected ) { + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed TEST:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); // same as above + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + _trb_connected = true; + } + + pdata_buf = callocMustSucceed( count, sizeof(epicsUInt32), "devTrbnet::processWaveform" ); + + int j,k,address; + int search_stat = 0 ; + int trb_Nmb=0, reg_Nmb=0, field_Nmb=0; + + for(i=0;ireg_name_buf) == 0){ + search_stat = 0; + } + else { + for(k=0;kreg_name_buf) == 0){ + address = trb[i].Reg[j].field[k].regAddr; + search_stat = 0; + trb_Nmb=i; reg_Nmb=j; field_Nmb=k; + } else { + search_stat = -1; + } + } + } + } + } + int data_size = 2; + if (search_stat){ + + //trb_stat = trb_register_readTESTFUNKTION( pinfo->trb_addr, address, pdata_buf, count ); + + trb_stat = trb_register_read( pinfo->trb_addr, address, pdata_buf, count ); + if ( -1 == trb_stat ) { + /* first try failed, do it again */ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + trb_stat = trb_register_read( pinfo->trb_addr, address, pdata_buf, count ); + if ( -1 == trb_stat ) { + fprintf( stderr, "\033[31;1m%s: read_register failed: %d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + free( pdata_buf ); + if (trb_errno == 12){ + prec->nelm = prec->nelm * 2; + } + recGblSetSevr( prec, READ_ALARM, INVALID_ALARM ); + _trb_connected = false; + return -1; + } + } + if ( TRB_STATUS_WARNING == trb_errno ) { + fprintf( stderr, "%s: Warning: Status-Bit(s) have been set:\n%s\n", + prec->name, trb_termstr( trb_term ) ); +// recGblSetSevr( prec, NULL, NULL ); + return -1; + } + + if ( trb_stat != prec->nelm ) { //> + /*int trb_stat_temp = trb_stat; + trb_stat = prec->nelm; + prec->nelm = trb_stat_temp;*/ + prec->nelm = trb_stat; + prec->bptr = realloc(prec->bptr, prec->nelm * dbValueSize(prec->ftvl)); + } + + double *pvalue = (epicsUInt32*)prec->bptr; + + + //---------------------------------------------------// + double output = -1; + epicsUInt32 start = pow(2, trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].start); + epicsUInt32 end = pow(2, trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].bits); + double scale = trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].scale; + +/* for( i=0; i < trb_stat; i+=2 ) { + output = ((pdata_buf[i+1]/start)%end )*scale; + pvalue[i] = pdata_buf[i]; + pvalue[i+1] = output; + } +*/ + for( i=0; i<( prec->nelm/2); i+=1 ){ + output = ((pdata_buf[(i*2)+1]/start)%end ) * scale; + pvalue[i] = pdata_buf[i*2]; + pvalue[i+(trb_stat/2)] = output; + } + + //---------------------------------------------------// + + } else { + printf("No Address Name %s found!\n", pinfo->reg_name_buf); + } +//--------------------------------// + prec->nord = trb_stat; + + free( pdata_buf ); + + return 0; +} + diff --git a/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet_test.c b/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet_test.c new file mode 100644 index 0000000..0c76021 --- /dev/null +++ b/Trbnet/devTrbnet/TrbnetApp/src/devTrbnet_test.c @@ -0,0 +1,869 @@ +/****** I N C L U D E S *******************************************************/ + +/* ANSI C includes */ +#include +#include +#include +#include +#include + +/* EPICS includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* local includes */ +#include "trberror.h" +#include "trbnet.h" + + +#define LINELENGTH 250 + +#define NumberOfBoards 1 + +#define __Name 0 +#define __Scale 1 +#define __Unit 2 +#define __Format 3 +#define __Start 4 +#define __Bits 5 +#define __Rate 6 +#define __ErrorFlag 7 +#define __InvertFlag 8 +#define __Value 9 + +/****** D E F I N I T I O N S **************************************************/ +static long initLi( longinRecord* prec ); +static long initLo( longoutRecord* prec ); +static long initWaveform( waveformRecord* prec ); +static long processLi( longinRecord* prec ); +static long processLo( longoutRecord* prec ); +static long processWaveform( waveformRecord* prec ); + +typedef struct { + long number; + DEVSUPFUN dev_report; + DEVSUPFUN init; + DEVSUPFUN init_record; + DEVSUPFUN get_ioint_info; + DEVSUPFUN process; +} dev_dset_trbnet_t; + +typedef struct { + epicsUInt16 trb_addr; + char* reg_name_buf; + char* reg_name_buf_nbr; + epicsUInt16 reg_addr; + //char entity_name[20]; +} trbnet_info_t; + +typedef struct{ + epicsUInt16 regAddr; + char *name; + float scale; + char *unit; + char *format; + int start; + int bits; + int rate; + char *errorflag; + char *invertflag; + int value; +}field_struct; + +typedef struct{ + epicsUInt16 regAddr; + char *name; + char *purpose; + field_struct *field; + int size; + int used; + int value; +}reg_struct; + +typedef struct{ + epicsUInt16 address; + char *name; + reg_struct *Reg; + size_t size; + size_t used; +}trb_struct; + +/****** G L O B A L S **********************************************************/ +dev_dset_trbnet_t dev_trbnet_li = { 6, NULL, NULL, initLi, NULL, processLi }; +dev_dset_trbnet_t dev_trbnet_lo = { 6, NULL, NULL, initLo, NULL, processLo }; +dev_dset_trbnet_t dev_trbnet_waveform = { 6, NULL, NULL, initWaveform, NULL, processWaveform }; +trb_struct *trb; +int databaseSet = 0; + +/****** L O C A L S ************************************************************/ +static bool _trb_connected = false; + +/****** F U N C T I O N S ******************************************************/ + +epicsExportAddress( dset, dev_trbnet_li ); +epicsExportAddress( dset, dev_trbnet_lo ); +epicsExportAddress( dset, dev_trbnet_waveform ); + +/*----- TEST FUNKTION ---------------------------------------------------------*/ +int trb_register_readTESTFUNKTION( uint16_t trb_addr, + uint16_t addr, + uint32_t *data, + unsigned int dsize) +{ + int status = 0; + if (trb_addr== 0) { + if (addr== 0) { + data[0] = 0; + //data[1]=21400000; + data[1] = 557842432; + } + return 2; + } + else if(trb_addr == 1) { + data[0] = 0; + data[1] = 557842432; + data[2] = 1; + data[3] = 557845532; + data[4] = 2; + data[5] = 557823451; + data[6] = 3; + data[7] = 557733332; + data[8] = 4; + data[9] = 667823451; + data[10] = 5; + data[11] = 598733332; + return 12; + } else { + return -1; + } +} + +int PadiwaSendCmd(uint32_t cmd, uint32_t board, uint32_t chain) { + + uint32_t c[] = { cmd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1<Reg[RegNumb].field = (field_struct *)malloc(sizeof(field_struct)); // 1 field + trb->Reg[RegNumb].used = 0; + trb->Reg[RegNumb].size = 1; + //Init with start values + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].regAddr = trb->Reg[RegNumb].regAddr; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].name = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].scale = 1; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].unit = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].format = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].start = 0; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].bits = 32; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].rate = -1; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].errorflag = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].invertflag = NULL; + trb->Reg[RegNumb].field[trb->Reg[RegNumb].used].value = -1; +} + +void initReg(trb_struct *trb, size_t initialSize) { + trb->Reg = (reg_struct *)malloc(initialSize * sizeof(reg_struct)); + trb->used = 0; + trb->size = initialSize; + int i=0; + for ( i; i < initialSize; i++) { + initField(trb, i); // trb_struct; i01= Element of Register + } +} + +// Insert a new field. Only RegAddress is Set from default +void insertField(reg_struct *reg) { + if (reg->used == reg->size) { + reg->size++; + reg->field = (field_struct *)realloc(reg->field, reg->size * sizeof(field_struct)); + } + //Init with start values + reg->field[reg->used].regAddr = reg->regAddr; //set register Address + reg->field[reg->used].name = NULL; + reg->field[reg->used].scale = 1; + reg->field[reg->used].unit = NULL; + reg->field[reg->used].format = NULL; + reg->field[reg->used].start = 0; + reg->field[reg->used].bits = 32; + reg->field[reg->used].rate = -1; + reg->field[reg->used].errorflag = NULL; + reg->field[reg->used].invertflag = NULL; + reg->field[reg->used].value = -1; + reg->used++; +} + +int setFieldPropertyInt(reg_struct *reg,int fieldNmb, int element, int data) { + if (fieldNmb < reg->used) { + if (element == __Start){ //field start + reg->field[fieldNmb].start = data; + } else if (element == __Bits){ //field bits + reg->field[fieldNmb].bits = data; + } else if (element == __Rate){ //field rate + reg->field[fieldNmb].rate = data; + } else if (element == __Value){ //field ratevalue + reg->field[fieldNmb].value = data; + } else { + printf("Element does not Fit to a INT Type property.\n"); + } + return 0; + } else { + return 1; //Error + } +} + +int setFieldPropertyStr(reg_struct *reg,int fieldNmb, int element, char *data) { + if (fieldNmb < reg->used) { + if(element == __Name){ //field NAME + reg->field[fieldNmb].name =strdup(data); + } else if (element == __Unit){ //field UNIT + reg->field[fieldNmb].unit = strdup(data); + } else if (element == __Format){ //field format + reg->field[fieldNmb].format = strdup(data); + } else if (element == __ErrorFlag){ //field errorflag + reg->field[fieldNmb].errorflag = strdup(data); + } else if (element == __InvertFlag){//field invertflag + reg->field[fieldNmb].invertflag = strdup(data); + } else { + printf("Element does not Fit to a STRING Type property.\n"); + } + return 0; + } else { + return 1; //Error; Field does not exist + } +} + +int setFieldPropertyFloat(reg_struct *reg, int fieldNmb, int element, float data) { + if (fieldNmb < reg->used) { + if (element == __Scale){ //field SCALE + reg->field[fieldNmb].scale = data; + } else { + printf("Element does not Fit to a FLOAT Type property.\n"); + } + return 0; + } else { + return 1; //Error; Field does not exist + } +} + +void insertReg(trb_struct *trb, int element) { + if (trb->used == trb->size) { + trb->size++; + trb->Reg = (reg_struct *)realloc(trb->Reg, trb->size * sizeof(reg_struct)); + } + trb->Reg[trb->used].regAddr = element; + initField(trb, trb->used); + trb->used++; +} + +// free the allocated memory of the fields of each Register +void freeField(trb_struct *trb) { + int i=0; + for (i;iused;i++){ + free(trb->Reg[i].field); + trb->Reg[i].field = NULL; + trb->Reg[i].used = trb->Reg[i].size = 0; + } +} + +// free the allocated memory of each register +void freeReg(trb_struct *trb) { + freeField(trb); + free(trb->Reg); + trb->Reg = NULL; + trb->used = trb->size = 0; +} + +/*----- Common initialization for all records ---------------------------------*/ + +static long initCommon( dbCommon* prec, DBLINK* plink ) { + + trbnet_info_t *pinfo; + char entity_name_buf[20] = ""; + char Reg_name_buf[20] = ""; + epicsUInt32 trb_addr_buf = 0; + epicsUInt32 reg_addr_buf = 0; + + char linebuffer[LINELENGTH]; + + if ( sscanf( plink->value.instio.string, "%s %x %s", entity_name_buf, &trb_addr_buf, Reg_name_buf ) != 3 ) { + fprintf( stderr, "\033[31;1m%s: Invalid value of INP/OUT field '%s'\033[0m\n", + prec->name, plink->value.instio.string ); + return -1; + } + if ( 0xffff < trb_addr_buf ) { + fprintf( stderr, "\033[31;1m%s: Invalid trb address '%x'\033[0m\n", + prec->name, trb_addr_buf ); + return -1; + } + + pinfo = callocMustSucceed( 1, sizeof(*pinfo), "devTrbnet::initCommon" ); + pinfo->trb_addr = (epicsUInt16)( trb_addr_buf & 0xffff ); +// pinfo->reg_name_buf = strdup(Reg_name_buf); + prec->dpvt = pinfo; + prec->udf = FALSE; + int i=0; + + // check special cases that are not inb XMLS Database + char * pname; +// char reg_name_buf[30]; +// strcpy(reg_name_buf, pinfo->reg_name_buf); + pname = strtok(Reg_name_buf,"_"); + pinfo->reg_name_buf = strdup(pname); + + while (pname != NULL){ +// printf("Ausgabe: %s\n",pname); + pinfo->reg_name_buf_nbr = strdup(pname); + pname = strtok(NULL," "); + + } +printf("test: %s\n",pinfo->reg_name_buf); +printf("test2: %s\n",pinfo->reg_name_buf_nbr); +//----------------------------------------------------------------// + + + +// create Memory for each TrbBoard + if (databaseSet==0) + { + trb = (trb_struct *) malloc(NumberOfBoards * sizeof(trb_struct)); + + for(i=0;i") == 0){ + group_open = false; + } + if (strcmp(node,"") == 0){ + register_open = false; + } + if (strcmp(node,"") == 0){ + field_open = false; + } + + // analyse each part of one line of .xml document + while(ptr != NULL) { + + if (group_open==true && register_open==false && field_open==false) { + sscanf(ptr, "address=\"%x\"", &gaddress); + sscanf(ptr, "name=\"%[A-z,_0-9]\"", gname); + sscanf(ptr, "mode=\"%[A-z,_,0-9]\"", gmode); + } + if (register_open==true && group_open==true && field_open==false){ + if(sscanf(ptr, "address=\"%x\"", ®_addr_buf)==1){ + pinfo->reg_addr = (epicsUInt16)( (reg_addr_buf + gaddress) & 0xffff ); + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].regAddr = pinfo->reg_addr; + } + } + if(sscanf(ptr, "name=\"%[A-z,_0-9]\"", rname)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].name = strdup(rname); + } + } + + if(sscanf(ptr, "purpose=\"%[A-z,_0-9]\"", purpose)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].purpose = strdup(purpose); + } + } + } + + if (field_open==true && group_open==true && register_open==true){ + if (strcmp(ptr,"/>\n") == 0){ + field_open=false; + } + if (sscanf(ptr, "name=\"%[A-z,_0-9]\"", fname)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].name = strdup(fname); + } + } + if (sscanf(ptr, "format=\"%[A-z,_0-9]\"", fformat)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].format = strdup(fformat); + } + } + if (sscanf(ptr, "bits=%*c%i%*c", &bits)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].bits = bits; + } + } + if (sscanf(ptr, "start=%*c%i%*c", &start)==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].start = start; + } + } + if (sscanf(ptr, "rate=%*c%i%*c", &rate )==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].rate = rate; + } + } + if (sscanf(ptr, "unit=%*c%x%*c", &unit )==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].unit = unit; + } + } + if (sscanf(ptr, "scale=%*c%f%*c", &scale )==1){ + for (i=0; i < NumberOfBoards; i++){ + trb[i].Reg[trb[i].used-1].field[trb[i].Reg[trb[i].used-1].used-1].scale = scale; + } + } + } + + ptr = strtok(NULL, delimiter); + }//end while2 + }//end while1 + + fclose(fp); + databaseSet = 1; + } + if ( 0xffff < reg_addr_buf ) { + fprintf( stderr, "\033[31;1m%s: Invalid register address '%x'\033[0m\n",prec->name, reg_addr_buf ); + return -1; + } + +//----------------------------------------------------------------------// + +/* // Test the fields + printf("Register Addres: %i\n", trb[0].Reg[8].regAddr); // getAddr of Register[0] + printf("Number of registers: %i\n", trb[0].size); // print number of fields in Register + printf("Number of fields:%i\n", trb[0].Reg[0].size); // print name of field 1 in Register 0 + printf("Number of fields:%s\n", trb[0].Reg[1].field[0].name); // print name of field 1 in Register 0 + printf("%i\n", trb[0].used); // getAddr of Register[0] +*/ +//---------------------------------------------------------------------------------------------// + /*free memory + for(i=0;ipact = (epicsUInt8)true; /* disable record */ + + status = initCommon( (dbCommon *)prec, &prec->inp ); + prec->pact = (epicsUInt8)false; /* enable record */ + + return status; +} + +/*----- initialization of longout records -------------------------------------*/ +static long initLo( longoutRecord* prec ) { + long status = 0; + prec->pact = (epicsUInt8)true; /* disable record */ + + status = initCommon( (dbCommon *)prec, &prec->out ); + prec->pact = (epicsUInt8)false; /* enable record */ + + return status; +} + +/*----- initialization of waveform records ------------------------------------*/ +static long initWaveform( waveformRecord* prec ) { + long status = 0; + prec->pact = (epicsUInt8)true; /* disable record */ + + if ( DBF_DOUBLE != prec->ftvl ) { + fprintf( stderr, "\033[31;1m%s: Invalid field type of value\033[0m\n", prec->name ); + return -1; + } + + status = initCommon( (dbCommon *)prec, &prec->inp ); + prec->pact = (epicsUInt8)false; /* enable record */ + + return status; +} + +/*----- process routine of longin records -------------------------------------*/ +static long processLi( longinRecord* prec ) { + trbnet_info_t* pinfo = (trbnet_info_t*)prec->dpvt; + epicsUInt32 data[2] = { 0 }; + int trb_stat = 0; + + int j,k,i,address; + int search_stat = 0 ; + int trb_Nmb=0, reg_Nmb=0, field_Nmb=0; + + if( !_trb_connected ){ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); // could be a problem (prec->name) + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + _trb_connected = true; + } + + + + // READ Address from Database + for(i=0;ireg_name_buf) == 0){ + search_stat = 0; + } + else { + for(k=0;kreg_name_buf) == 0){ + address = trb[i].Reg[j].field[k].regAddr; + search_stat = 0; + trb_Nmb=i; reg_Nmb=j; field_Nmb=k; + } else { + search_stat = -1; + } + } + } + } + } + + if (search_stat){ + int data_size = 2; + trb_stat = trb_register_read( pinfo->trb_addr, address, data, data_size ); + //trb_stat = trb_register_readTESTFUNKTION( pinfo->trb_addr, address, data, data_size ); + + //--------------------------------------// + if ( -1 == trb_stat ) { + /* first try failed, do it again */ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + trb_stat = trb_register_read( pinfo->trb_addr, address, data, data_size ); + if ( -1 == trb_stat ) { + /* second try failed, return error */ + fprintf( stderr, "\033[31;1m%s: read_register failed: %d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, READ_ALARM, INVALID_ALARM ); + _trb_connected = false; + return -1; + } + } + /* Check Status-Bits */ + if ( TRB_STATUS_WARNING == trb_errno ) { + fprintf( stderr, "%s: Warning: Status-Bit(s) have been set:\n%s\n", + prec->name, trb_termstr( trb_term ) ); + recGblSetSevr( prec, NULL, NULL); + return -1; + } + //------------------------------// + double output = -1; + epicsUInt32 start = pow(2, trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].start); + epicsUInt32 end = pow(2, trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].bits); + double scale = trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].scale; + + for (i=0; i< data_size;i+=2){ + output = ((data[i+1]/start)%end )*scale; + prec->val = output; + } + //--------------------------------// + + } else { + printf("No Address Name %s found!\n", pinfo->reg_name_buf); + } + + + return 0; +} + +//----- LONGOUT IS NOT IN USE!!!-----------------------------------------------// +/*----- process routine of longout records ------------------------------------*/ +static long processLo( longoutRecord* prec ) { + trbnet_info_t* pinfo = (trbnet_info_t*)prec->dpvt; + epicsUInt32 value = prec->val; + int trb_stat = 0; + + if( !_trb_connected ) { + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + _trb_connected = true; + } + + trb_stat = trb_register_write( pinfo->trb_addr, pinfo->reg_addr, value ); + if ( -1 == trb_stat ) { + /* first try failed, do it again */ + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + trb_stat = trb_register_write( pinfo->trb_addr, pinfo->reg_addr, value ); + if ( -1 == trb_stat ) { + /* second try failed, return error */ + fprintf( stderr, "\033[31;1m%s: write_register failed: %d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, WRITE_ALARM, INVALID_ALARM ); + _trb_connected = false; + return -1; + } + } + if ( TRB_STATUS_WARNING == trb_errno ) { + fprintf( stderr, "%s: Warning: Status-Bit(s) have been set:\n%s\n", + prec->name, trb_termstr( trb_term ) ); + return -1; + } + + return 0; +} + +/*----- process routine of waveform records -----------------------------------*/ +static long processWaveform( waveformRecord* prec ) { + trbnet_info_t *pinfo = (trbnet_info_t*)prec->dpvt; + epicsUInt32 *pdata_buf; + epicsUInt32 count = 200;//prec->nelm; // equal to 100 boards + int trb_stat = 0; + int i = 0; + + +/* if( !_trb_connected ) { + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed TEST:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); // same as above + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + _trb_connected = true; + } +*/ + pdata_buf = callocMustSucceed( count, sizeof(epicsUInt32), "devTrbnet::processWaveform" ); + + int j,k,address; + int search_stat = -1 ; + int trb_Nmb=0, reg_Nmb=0, field_Nmb=0; + + if (strcmp(pinfo->reg_name_buf, "ADC") == 0){ + search_stat = 1; +} else { + + for(i=0;i= 0){ + //run without doing smtng + } else { + if (strcmp(trb[i].Reg[j].name,pinfo->reg_name_buf) == 0){ + search_stat = 0; + } + else { + for(k=0;kreg_name_buf)); + + if (strcmp(trb[i].Reg[j].field[k].name, pinfo->reg_name_buf) == 0){ + address = trb[i].Reg[j].field[k].regAddr; + search_stat = 0; + trb_Nmb=i; reg_Nmb=j; field_Nmb=k; + } else { + search_stat = -1; + } + } + } + }//search_stat end if + } + } + +} + + int data_size = 2; + unsigned int mode = 0; + + if (search_stat == 1){ + int channel[5] = {7,7,7,6,5}; + int resolution[5][4] = {{2,1,2,1},{2,2,2,1},{2,2,2,4},{2,2,2,2},{3,3,2,2}}; + double multiplier[5][4] = {{1.,1.,0.5,2.},{1.,1.,0.5,0.},{1.,1.,0.5,3.125},{1.,1.,0.5,0.5},{2.5,1.25,1.,0.5}}; + int cmd = 0; + + if (atoi(pinfo->reg_name_buf_nbr)>=0 && atoi(pinfo->reg_name_buf_nbr)<5) { + mode = atoi(pinfo->reg_name_buf_nbr); + } else { + mode = 0; + } +fprintf(stderr,"TEST PLlace\n"); + //prec->nelm = 10; + //prec->bptr = realloc(prec->bptr, prec->nelm * dbValueSize(prec->ftvl)); + + double *pvalue = (epicsUInt32*)prec->bptr; + + pvalue[0] = 3; + pvalue[1] = 5; + pvalue[2] = 4; + pvalue[3] = 1; + + +/* double output = -1; + for( i=0; i<( prec->nelm/2); i+=1 ){ + output = 2.;//((pdata_buf[(i*2)+1]/start)%end ) * scale; + pvalue[i] = 5.;//pdata_buf[i*2]; + pvalue[prec->nelm/2 + i] = output; + } +*/ + + cmd = 0xc1830000 + ( resolution[mode][0] << 25); +/* trb_register_write(0x8300,pinfo->trb_addr,25); + PadiwaSendCmd(cmd,pinfo->trb_addr,channel[mode]); + usleep(5000); + cmd = 0xd1830000 + ( resolution[mode][1] << 25); + fprintf(stderr," 1: %f \n",(double) ((( PadiwaSendCmd(cmd,pinfo->trb_addr,channel[mode])>>19)&0xfff)*multiplier[mode][0])); + usleep(5000); + cmd = 0xe1830000 + ( resolution[mode][2] << 25); + fprintf(stderr," 2: %f \n",(double) ((( PadiwaSendCmd(cmd,pinfo->trb_addr,channel[mode])>>19)&0xfff)*multiplier[mode][1]) ); + usleep(1000); + cmd = 0xf1830000 + ( resolution[mode][3] << 25); + fprintf(stderr," 3: %f \n",(double) ((( PadiwaSendCmd(cmd,pinfo->trb_addr,channel[mode])>>19)&0xfff)*multiplier[mode][2]) ); + usleep(5000); + fprintf(stderr," 4: %f \n",(double) (((PadiwaSendCmd(0xf3930000,pinfo->trb_addr,channel[mode])>>19)&0xfff)*multiplier[mode][3]) ); + usleep(5000); + fprintf(stderr," 5: %3.2f \n", (double) (((PadiwaSendCmd(0,pinfo->trb_addr,channel[mode])>>19)&0xfff)/16.)); + + trb_register_write(pinfo->trb_addr,0xd41a,7); +*/ + } else if (search_stat == 0) { + /* trb_stat = trb_register_read( pinfo->trb_addr, address, pdata_buf, count ); + if ( -1 == trb_stat ) { + if( init_ports() == -1 ) { + fprintf( stderr, "\033[31;1m%s: init_ports failed:\n%d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + recGblSetSevr( prec, COMM_ALARM, INVALID_ALARM ); + return -1; + } + trb_stat = trb_register_read( pinfo->trb_addr, address, pdata_buf, count ); + if ( -1 == trb_stat ) { + fprintf( stderr, "\033[31;1m%s: read_register failed: %d %s\033[0m\n", + prec->name, trb_errno, trb_strerror() ); + free( pdata_buf ); + if (trb_errno == 12){ + prec->nelm = prec->nelm * 2; + } + recGblSetSevr( prec, READ_ALARM, INVALID_ALARM ); + _trb_connected = false; + return -1; + } + } + if ( TRB_STATUS_WARNING == trb_errno ) { + fprintf( stderr, "%s: Warning: Status-Bit(s) have been set:\n%s\n", + prec->name, trb_termstr( trb_term ) ); +// recGblSetSevr( prec, NULL, NULL ); + return -1; + } +*/ +fprintf(stderr,"PREC: %d",prec->nelm); +//trb_stat=10;//pdata_buf[0]=2; +// if ( trb_stat != prec->nelm ) { //> +// prec->nelm = trb_stat; + prec->bptr = realloc(prec->bptr, prec->nelm * dbValueSize(prec->ftvl)); +// } + + double *pvalue = (epicsUInt32*)prec->bptr; + + + //---------------------------------------------------// + double output = -1; + epicsUInt32 start = pow(2, trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].start); + epicsUInt32 end = pow(2, trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].bits); + double scale = trb[trb_Nmb].Reg[reg_Nmb].field[field_Nmb].scale; + +/* for( i=0; i < trb_stat; i+=2 ) { + output = ((pdata_buf[i+1]/start)%end )*scale; + pvalue[i] = pdata_buf[i]; + pvalue[i+1] = output; + } +*/ + for( i=0; i<( prec->nelm); i+=1 ){ +// output = ((pdata_buf[(i*2)+1]/start)%end ) * scale; + pvalue[i] = 3.34;//pdata_buf[i]; +// pvalue[i+(trb_stat/2)] = pdata_buf[i+];//output; + } + + //---------------------------------------------------// + + } else { + printf("No Address Name %s found!\n", pinfo->reg_name_buf); + } +//--------------------------------// + prec->nord = 10;//trb_stat; + + free( pdata_buf ); + + return 0; +} + diff --git a/Trbnet/devTrbnet/iocBoot/iocTrbnet/st.cmd b/Trbnet/devTrbnet/iocBoot/iocTrbnet/st.cmd index 1f33260..7d487af 100644 --- a/Trbnet/devTrbnet/iocBoot/iocTrbnet/st.cmd +++ b/Trbnet/devTrbnet/iocBoot/iocTrbnet/st.cmd @@ -3,6 +3,7 @@ < envPaths epicsEnvSet("EPICS_TRBNET_XML_PATH","/home/adrian/trb/daqtools/xml-db/database/") epicsEnvSet("EPICS_TRBNET_XML_NAME","MDC") +#epicsEnvSet("EPICS_TRBNET_XML_NAME","TrbNet") cd ${TOP}