diff --git a/src/rec/recAi.c b/src/rec/recAi.c index 02a2d1387..dbc252c28 100644 --- a/src/rec/recAi.c +++ b/src/rec/recAi.c @@ -64,6 +64,11 @@ * .24 04-10-92 jba pact now used to test for asyn processing, not status * .25 04-18-92 jba removed process from dev init_record parms * .26 06-02-92 jba changed graphic/control limits for hihi,high,low,lolo + * .28 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .29 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .30 07-21-92 jba changed alarm limits for non val related fields + * .31 08-06-92 jba New algorithm for calculating analog alarms + * .32 08-13-92 jba Added simulation processing */ #include @@ -73,6 +78,7 @@ #include #include +#include #include #include #include @@ -101,7 +107,7 @@ static long get_precision(); static long get_graphic_double(); static long get_control_double(); static long get_alarm_double(); - + struct rset aiRSET={ RSETNUMBER, report, @@ -137,10 +143,10 @@ struct aidset { /* analog input dset */ /*Following from timing system */ extern unsigned int gts_trigger_counter; -void alarm(); -void convert(); -long cvtRawToEngBpt(); -void monitor(); +static void alarm(); +static void convert(); +static void monitor(); +static long readValue(); static long init_record(pai,pass) struct aiRecord *pai; @@ -151,13 +157,47 @@ static long init_record(pai,pass) if (pass==0) return(0); + /* ai.siml must be a CONSTANT or a PV_LINK or a DB_LINK */ + switch (pai->siml.type) { + case (CONSTANT) : + pai->simm = pai->siml.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(pai->siml), (void *) pai, "SIMM"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)pai, + "ai: init_record Illegal SIML field"); + return(S_db_badField); + } + + /* ai.siol must be a CONSTANT or a PV_LINK or a DB_LINK */ + switch (pai->siol.type) { + case (CONSTANT) : + pai->sval = pai->siol.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(pai->siol), (void *) pai, "SVAL"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)pai, + "ai: init_record Illegal SIOL field"); + return(S_db_badField); + } + if(!(pdset = (struct aidset *)(pai->dset))) { - recGblRecordError(S_dev_noDSET,pai,"ai: init_record"); + recGblRecordError(S_dev_noDSET,(void *)pai,"ai: init_record"); return(S_dev_noDSET); } /* must have read_ai function defined */ if( (pdset->number < 6) || (pdset->read_ai == NULL) ) { - recGblRecordError(S_dev_missingSup,pai,"ai: init_record"); + recGblRecordError(S_dev_missingSup,(void *)pai,"ai: init_record"); return(S_dev_missingSup); } pai->init = TRUE; @@ -177,7 +217,7 @@ static long process(pai) if( (pdset==NULL) || (pdset->read_ai==NULL) ) { pai->pact=TRUE; - recGblRecordError(S_dev_missingSup,pai,"read_ai"); + recGblRecordError(S_dev_missingSup,(void *)pai,"read_ai"); return(S_dev_missingSup); } @@ -190,7 +230,7 @@ static long process(pai) } } - status=(*pdset->read_ai)(pai); /* read the new value */ + status=readValue(pai); /* read the new value */ /* check if device support set pact */ if ( !pact && pai->pact ) return(0); pai->pact = TRUE; @@ -204,7 +244,7 @@ static long process(pai) /* check event list */ monitor(pai); /* process the forward scan link record */ - if (pai->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)pai->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(pai); pai->init=FALSE; pai->pact=FALSE; @@ -306,51 +346,56 @@ static long get_alarm_double(paddr,pad) { struct aiRecord *pai=(struct aiRecord *)paddr->precord; - pad->upper_alarm_limit = pai->hihi; - pad->upper_warning_limit = pai->high; - pad->lower_warning_limit = pai->low; - pad->lower_alarm_limit = pai->lolo; + if(paddr->pfield==(void *)&pai->val){ + pad->upper_alarm_limit = pai->hihi; + pad->upper_warning_limit = pai->high; + pad->lower_warning_limit = pai->low; + pad->lower_alarm_limit = pai->lolo; + } else recGblGetAlarmDouble(paddr,pad); return(0); } static void alarm(pai) struct aiRecord *pai; { - double ftemp; - double val=pai->val; + double val; + float hyst, lalm, hihi, high, low, lolo; + unsigned short hhsv, llsv, hsv, lsv; if(pai->udf == TRUE ){ - recGblSetSevr(pai,UDF_ALARM,VALID_ALARM); + recGblSetSevr(pai,UDF_ALARM,INVALID_ALARM); return; } - /* if difference is not > hysterisis use lalm not val */ - ftemp = pai->lalm - pai->val; - if(ftemp<0.0) ftemp = -ftemp; - if (ftemp < pai->hyst) val=pai->lalm; + hihi = pai->hihi; lolo = pai->lolo; high = pai->high; low = pai->low; + hhsv = pai->hhsv; llsv = pai->llsv; hsv = pai->hsv; lsv = pai->lsv; + val = pai->val; hyst = pai->hyst; lalm = pai->lalm; /* alarm condition hihi */ - if (val > pai->hihi && recGblSetSevr(pai,HIHI_ALARM,pai->hhsv)){ - pai->lalm = val; + if (hhsv && (val >= hihi || ((lalm==hihi) && (val >= hihi-hyst)))){ + if (recGblSetSevr(pai,HIHI_ALARM,pai->hhsv)) pai->lalm = hihi; return; } /* alarm condition lolo */ - if (val < pai->lolo && recGblSetSevr(pai,LOLO_ALARM,pai->llsv)){ - pai->lalm = val; + if (llsv && (val <= lolo || ((lalm==lolo) && (val <= lolo+hyst)))){ + if (recGblSetSevr(pai,LOLO_ALARM,pai->llsv)) pai->lalm = lolo; return; } /* alarm condition high */ - if (val > pai->high && recGblSetSevr(pai,HIGH_ALARM,pai->hsv)){ - pai->lalm = val; + if (hsv && (val >= high || ((lalm==high) && (val >= high-hyst)))){ + if (recGblSetSevr(pai,HIGH_ALARM,pai->hsv)) pai->lalm = high; return; } /* alarm condition low */ - if (val < pai->low && recGblSetSevr(pai,LOW_ALARM,pai->lsv)){ - pai->lalm = val; + if (lsv && (val <= low || ((lalm==low) && (val <= low+hyst)))){ + if (recGblSetSevr(pai,LOW_ALARM,pai->lsv)) pai->lalm = low; return; } + + /* we get here only if val is out of alarm by at least hyst */ + pai->lalm = val; return; } @@ -375,8 +420,8 @@ struct aiRecord *pai; val = (val * pai->eslo) + pai->egul; } else { /* must use breakpoint table */ - if (cvtRawToEngBpt(&val,pai->linr,pai->init,&pai->pbrk,&pai->lbrk)!=0) { - recGblSetSevr(pai,SOFT_ALARM,VALID_ALARM); + if (cvtRawToEngBpt(&val,pai->linr,pai->init,(void *)&pai->pbrk,&pai->lbrk)!=0) { + recGblSetSevr(pai,SOFT_ALARM,INVALID_ALARM); } } @@ -441,3 +486,42 @@ static void monitor(pai) } return; } + +static long readValue(pai) + struct aiRecord *pai; +{ + long status; + struct aidset *pdset = (struct aidset *) (pai->dset); + long nRequest=1; + + if (pai->pact == TRUE){ + status=(*pdset->read_ai)(pai); + return(status); + } + + status=recGblGetLinkValue(&(pai->siml), + (void *)pai,DBR_ENUM,&(pai->simm),&nRequest); + if (status) + return(status); + + if (pai->simm == NO){ + status=(*pdset->read_ai)(pai); + return(status); + } + if (pai->simm == YES){ + status=recGblGetLinkValue(&(pai->siol), + (void *)pai,DBR_DOUBLE,&(pai->sval),&nRequest); + if (status==0){ + pai->val=pai->sval; + pai->udf=FALSE; + } + status=2; /* dont convert */ + } else { + status=-1; + recGblSetSevr(pai,SOFT_ALARM,INVALID_ALARM); + return(status); + } + recGblSetSevr(pai,SIMM_ALARM,pai->sims); + + return(status); +} diff --git a/src/rec/recAo.c b/src/rec/recAo.c index 2ef98ac5c..5e5a66545 100644 --- a/src/rec/recAo.c +++ b/src/rec/recAo.c @@ -58,6 +58,13 @@ * .25 04-10-92 jba pact now used to test for asyn processing, not status * .26 04-18-92 jba removed process from dev init_record parms * .27 06-02-92 jba changed graphic/control limits for hihi,high,low,lolo + * .28 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .29 07-16-92 jba added invalid alrm fwd lnk test & chngd fwd lnk to macro + * .30 07-21-92 jba changed alarm limits for non val related fields + * .31 08-06-92 jba New algorithm for calculating analog alarms + * .32 08-19-92 jba Added simulation processing + * .33 08-19-92 jba Added code for invalid alarm output action + */ #include @@ -67,6 +74,7 @@ #include #include +#include #include #include #include @@ -130,12 +138,11 @@ struct aodset { /* analog input dset */ #define OUTPUT_FULL 0 #define OUTPUT_INCREMENTAL 1 -void alarm(); -int convert(); -long cvtRawToEngBpt(); -long cvtEngToRawBpt(); -void monitor(); - +static void alarm(); +static void fetch_value(); +static void convert(); +static void monitor(); +static long writeValue(); static long init_record(pao,pass) struct aoRecord *pao; @@ -147,8 +154,31 @@ static long init_record(pao,pass) if (pass==0) return(0); + /* ao.siml must be a CONSTANT or a PV_LINK or a DB_LINK */ + switch (pao->siml.type) { + case (CONSTANT) : + pao->simm = pao->siml.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(pao->siml), (void *) pao, "SIMM"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)pao, + "ao: init_record Illegal SIML field"); + return(S_db_badField); + } + + /* ao.siol may be a PV_LINK */ + if (pao->siol.type == PV_LINK){ + status = dbCaAddOutlink(&(pao->siol), (void *) pao, "OVAL"); + if(status) return(status); + } + if(!(pdset = (struct aodset *)(pao->dset))) { - recGblRecordError(S_dev_noDSET,pao,"ao: init_record"); + recGblRecordError(S_dev_noDSET,(void *)pao,"ao: init_record"); return(S_dev_noDSET); } /* get the initial value if dol is a constant*/ @@ -158,7 +188,7 @@ static long init_record(pao,pass) } /* must have write_ao function defined */ if( (pdset->number < 6) || (pdset->write_ao ==NULL) ) { - recGblRecordError(S_dev_missingSup,pao,"ao: init_record"); + recGblRecordError(S_dev_missingSup,(void *)pao,"ao: init_record"); return(S_dev_missingSup); } pao->init = TRUE; @@ -175,7 +205,7 @@ static long init_record(pao,pass) pao->udf=FALSE; }else{ value=pao->rval; - if (cvtRawToEngBpt(&value,pao->linr,pao->init,&pao->pbrk,&pao->lbrk)==0){ + if (cvtRawToEngBpt(&value,pao->linr,pao->init,(void *)&pao->pbrk,&pao->lbrk)==0){ pao->val=value; pao->udf=FALSE; } @@ -184,7 +214,7 @@ static long init_record(pao,pass) case(2): /* no convert */ break; default: - recGblRecordError(S_dev_badInitRet,pao,"ao: init_record"); + recGblRecordError(S_dev_badInitRet,(void *)pao,"ao: init_record"); return(S_dev_badInitRet); break; } @@ -199,33 +229,58 @@ static long process(pao) struct aodset *pdset = (struct aodset *)(pao->dset); long status=0; unsigned char pact=pao->pact; + double value; if( (pdset==NULL) || (pdset->write_ao==NULL) ) { pao->pact=TRUE; - recGblRecordError(S_dev_missingSup,pao,"write_ao"); + recGblRecordError(S_dev_missingSup,(void *)pao,"write_ao"); return(S_dev_missingSup); } - if(pao->pact == FALSE) { /* convert and if success write*/ - if(convert(pao)==0) status=(*pdset->write_ao)(pao); - } else { - status=(*pdset->write_ao)(pao); + /* fetch value and convert*/ + if(pao->pact == FALSE){ + fetch_value(pao,&value); + convert(pao,&value); } + + /* check for alarms */ + alarm(pao); + + if (pao->nsev < INVALID_ALARM ) + status=writeValue(pao); /* write the new value */ + else { + switch (pao->ivoa) { + case (IVOA_CONTINUE) : + status=writeValue(pao); /* write the new value */ + break; + case (IVOA_NO_OUTPUT) : + break; + case (IVOA_OUTPUT_IVOV) : + if(pao->pact == FALSE){ + pao->val=pao->ivov; + value=pao->ivov; + convert(pao,&value); + } + status=writeValue(pao); /* write the new value */ + break; + default : + status=-1; + recGblRecordError(S_db_badField,(void *)pao, + "ao:process Illegal IVOA field"); + } + } + /* check if device support set pact */ if ( !pact && pao->pact ) return(0); pao->pact = TRUE; tsLocalTime(&pao->time); - /* check for alarms */ - alarm(pao); - - /* check event list */ monitor(pao); /* process the forward scan link record */ - if (pao->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)pao->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(pao); pao->init=FALSE; pao->pact=FALSE; @@ -264,7 +319,7 @@ static long get_value(pao,pvdes) (double *)(pvdes->pvalue) = &pao->val; return(0); } - + static long get_units(paddr,units) struct dbAddr *paddr; char *units; @@ -288,7 +343,7 @@ static long get_precision(paddr,precision) recGblGetPrec(paddr,precision); return(0); } - + static long get_graphic_double(paddr,pgd) struct dbAddr *paddr; struct dbr_grDouble *pgd; @@ -332,60 +387,63 @@ static long get_alarm_double(paddr,pad) { struct aoRecord *pao=(struct aoRecord *)paddr->precord; - pad->upper_alarm_limit = pao->hihi; - pad->upper_warning_limit = pao->high; - pad->lower_warning_limit = pao->low; - pad->lower_alarm_limit = pao->lolo; + if(paddr->pfield==(void *)&pao->val){ + pad->upper_alarm_limit = pao->hihi; + pad->upper_warning_limit = pao->high; + pad->lower_warning_limit = pao->low; + pad->lower_alarm_limit = pao->lolo; + } else recGblGetAlarmDouble(paddr,pad); return(0); } - static void alarm(pao) struct aoRecord *pao; { - double ftemp; - double val=pao->val; + double val; + float hyst, lalm, hihi, high, low, lolo; + unsigned short hhsv, llsv, hsv, lsv; - if(pao->udf == TRUE ){ - recGblSetSevr(pao,UDF_ALARM,VALID_ALARM); - return; - } + if(pao->udf == TRUE ){ + recGblSetSevr(pao,UDF_ALARM,INVALID_ALARM); + return; + } + hihi = pao->hihi; lolo = pao->lolo; high = pao->high; low = pao->low; + hhsv = pao->hhsv; llsv = pao->llsv; hsv = pao->hsv; lsv = pao->lsv; + val = pao->val; hyst = pao->hyst; lalm = pao->lalm; - /* if difference is not > hysterisis use lalm not val */ - ftemp = pao->lalm - pao->val; - if(ftemp<0.0) ftemp = -ftemp; - if (ftemp < pao->hyst) val=pao->lalm; + /* alarm condition hihi */ + if (hhsv && (val >= hihi || ((lalm==hihi) && (val >= hihi-hyst)))){ + if (recGblSetSevr(pao,HIHI_ALARM,pao->hhsv)) pao->lalm = hihi; + return; + } - /* alarm condition hihi */ - if (val > pao->hihi && recGblSetSevr(pao,HIHI_ALARM,pao->hhsv)){ - pao->lalm = val; - return; - } + /* alarm condition lolo */ + if (llsv && (val <= lolo || ((lalm==lolo) && (val <= lolo+hyst)))){ + if (recGblSetSevr(pao,LOLO_ALARM,pao->llsv)) pao->lalm = lolo; + return; + } - /* alarm condition lolo */ - if (val < pao->lolo && recGblSetSevr(pao,LOLO_ALARM,pao->llsv)){ - pao->lalm = val; - return; - } + /* alarm condition high */ + if (hsv && (val >= high || ((lalm==high) && (val >= high-hyst)))){ + if (recGblSetSevr(pao,HIGH_ALARM,pao->hsv)) pao->lalm = high; + return; + } - /* alarm condition high */ - if (val > pao->high && recGblSetSevr(pao,HIGH_ALARM,pao->hsv)){ - pao->lalm = val; - return; - } + /* alarm condition low */ + if (lsv && (val <= low || ((lalm==low) && (val <= low+hyst)))){ + if (recGblSetSevr(pao,LOW_ALARM,pao->lsv)) pao->lalm = low; + return; + } - /* alarm condition low */ - if (val < pao->low && recGblSetSevr(pao,LOW_ALARM,pao->lsv)){ - pao->lalm = val; - return; - } - return; + /* we get here only if val is out of alarm by at least hyst */ + pao->lalm = val; + return; } -static int convert(pao) +static void fetch_value(pao,pvalue) struct aoRecord *pao; + double *pvalue; { - double value; if ((pao->dol.type == DB_LINK) && (pao->omsl == CLOSED_LOOP)){ long nRequest; @@ -400,15 +458,24 @@ static int convert(pao) /* don't allow dbputs to val field */ pao->val=pao->pval; status = dbGetLink(&pao->dol.value.db_link,(struct dbCommon *)pao,DBR_DOUBLE, - &value,&options,&nRequest); + pvalue,&options,&nRequest); pao->pact = save_pact; if(status) { - recGblSetSevr(pao,LINK_ALARM,VALID_ALARM); - return(1); + recGblSetSevr(pao,LINK_ALARM,INVALID_ALARM); + return; } - if (pao->oif == OUTPUT_INCREMENTAL) value += pao->val; - } else value = pao->val; + if (pao->oif == OUTPUT_INCREMENTAL) *pvalue += pao->val; + } else *pvalue = pao->val; + return; +} + +static void convert(pao,pvalue) + struct aoRecord *pao; + double *pvalue; +{ + double value; + value=*pvalue; /* check drive limits */ if(pao->drvh > pao->drvl) { if (value > pao->drvh) value = pao->drvh; @@ -440,13 +507,13 @@ static int convert(pao) pao->rval -= pao->roff; } }else{ - if(cvtEngToRawBpt(&value,pao->linr,pao->init,&pao->pbrk,&pao->lbrk)!=0){ - recGblSetSevr(pao,SOFT_ALARM,VALID_ALARM); - return(1); + if(cvtEngToRawBpt(&value,pao->linr,pao->init,(void *)&pao->pbrk,&pao->lbrk)!=0){ + recGblSetSevr(pao,SOFT_ALARM,INVALID_ALARM); + return; } pao->rval=value; } - return(0); + return; } @@ -508,3 +575,37 @@ static void monitor(pao) } return; } + +static long writeValue(pao) + struct aoRecord *pao; +{ + long status; + struct aodset *pdset = (struct aodset *) (pao->dset); + long nRequest=1; + + if (pao->pact == TRUE){ + status=(*pdset->write_ao)(pao); + return(status); + } + + status=recGblGetLinkValue(&(pao->siml), + (void *)pao,DBR_ENUM,&(pao->simm),&nRequest); + if (status) + return(status); + + if (pao->simm == NO){ + status=(*pdset->write_ao)(pao); + return(status); + } + if (pao->simm == YES){ + status=recGblPutLinkValue(&(pao->siol), + (void *)pao,DBR_DOUBLE,&(pao->oval),&nRequest); + } else { + status=-1; + recGblSetSevr(pao,SOFT_ALARM,INVALID_ALARM); + return(status); + } + recGblSetSevr(pao,SIMM_ALARM,pao->sims); + + return(status); +} diff --git a/src/rec/recBi.c b/src/rec/recBi.c index 3d6471cb4..470e734d2 100644 --- a/src/rec/recBi.c +++ b/src/rec/recBi.c @@ -50,6 +50,9 @@ * .16 02-28-92 jba ANSI C changes * .17 04-10-92 jba pact now used to test for asyn processing, not status * .18 04-18-92 jba removed process from dev init_record parms + * .19 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .20 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .21 08-13-92 jba Added simulation processing */ #include @@ -113,8 +116,9 @@ struct bidset { /* binary input dset */ DEVSUPFUN read_bi;/*(0,2)=> success and convert, don't convert)*/ /* if convert then raw value stored in rval */ }; -void alarm(); -void monitor(); +static void alarm(); +static void monitor(); +static long readValue(); static long init_record(pbi,pass) struct biRecord *pbi; @@ -125,13 +129,47 @@ static long init_record(pbi,pass) if (pass==0) return(0); + /* bi.siml must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ + switch (pbi->siml.type) { + case (CONSTANT) : + pbi->simm = pbi->siml.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(pbi->siml), (void *) pbi, "SIMM"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)pbi, + "bi: init_record Illegal SIML field"); + return(S_db_badField); + } + + /* bi.siol must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ + switch (pbi->siol.type) { + case (CONSTANT) : + pbi->sval = pbi->siol.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(pbi->siol), (void *) pbi, "SVAL"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)pbi, + "bi: init_record Illegal SIOL field"); + return(S_db_badField); + } + if(!(pdset = (struct bidset *)(pbi->dset))) { - recGblRecordError(S_dev_noDSET,pbi,"bi: init_record"); + recGblRecordError(S_dev_noDSET,(void *)pbi,"bi: init_record"); return(S_dev_noDSET); } /* must have read_bi function defined */ if( (pdset->number < 5) || (pdset->read_bi == NULL) ) { - recGblRecordError(S_dev_missingSup,pbi,"bi: init_record"); + recGblRecordError(S_dev_missingSup,(void *)pbi,"bi: init_record"); return(S_dev_missingSup); } if( pdset->init_record ) { @@ -149,11 +187,11 @@ static long process(pbi) if( (pdset==NULL) || (pdset->read_bi==NULL) ) { pbi->pact=TRUE; - recGblRecordError(S_dev_missingSup,pbi,"read_bi"); + recGblRecordError(S_dev_missingSup,(void *)pbi,"read_bi"); return(S_dev_missingSup); } - status=(*pdset->read_bi)(pbi); /* read the new value */ + status=readValue(pbi); /* read the new value */ /* check if device support set pact */ if ( !pact && pbi->pact ) return(0); pbi->pact = TRUE; @@ -170,7 +208,7 @@ static long process(pbi) /* check event list */ monitor(pbi); /* process the forward scan link record */ - if (pbi->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)pbi->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(pbi); pbi->pact=FALSE; return(status); @@ -236,7 +274,7 @@ static void alarm(pbi) if(pbi->udf == TRUE){ - recGblSetSevr(pbi,UDF_ALARM,VALID_ALARM); + recGblSetSevr(pbi,UDF_ALARM,INVALID_ALARM); return; } @@ -292,3 +330,42 @@ static void monitor(pbi) } return; } + +static long readValue(pbi) + struct biRecord *pbi; +{ + long status; + struct bidset *pdset = (struct bidset *) (pbi->dset); + long nRequest=1; + + if (pbi->pact == TRUE){ + status=(*pdset->read_bi)(pbi); + return(status); + } + + status=recGblGetLinkValue(&(pbi->siml), + (void *)pbi,DBR_ENUM,&(pbi->simm),&nRequest); + if (status) + return(status); + + if (pbi->simm == NO){ + status=(*pdset->read_bi)(pbi); + return(status); + } + if (pbi->simm == YES){ + status=recGblGetLinkValue(&(pbi->siol), + (void *)pbi,DBR_USHORT,&(pbi->sval),&nRequest); + if (status==0){ + pbi->val=pbi->sval; + pbi->udf=FALSE; + } + status=2; /* dont convert */ + } else { + status=-1; + recGblSetSevr(pbi,SOFT_ALARM,INVALID_ALARM); + return(status); + } + recGblSetSevr(pbi,SIMM_ALARM,pbi->sims); + + return(status); +} diff --git a/src/rec/recBo.c b/src/rec/recBo.c index fe7be86c7..3d308eaae 100644 --- a/src/rec/recBo.c +++ b/src/rec/recBo.c @@ -58,6 +58,10 @@ * .22 03-03-92 jba Changed callback handling * .23 04-10-92 jba pact now used to test for asyn processing, not status * .24 04-18-92 jba removed process from dev init_record parms + * .25 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .26 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .27 08-14-92 jba Added simulation processing + * .28 08-19-92 jba Added code for invalid alarm output action */ #include @@ -135,11 +139,11 @@ struct callback { WDOG_ID wd_id; }; +static void alarm(); +static void monitor(); +static long writeValue(); + void callbackRequest(); -void alarm(); -void monitor(); - - static void myCallback(pcallback) struct callback *pcallback; @@ -164,13 +168,36 @@ static long init_record(pbo,pass) if (pass==0) return(0); + /* bo.siml must be a CONSTANT or a PV_LINK or a DB_LINK */ + switch (pbo->siml.type) { + case (CONSTANT) : + pbo->simm = pbo->siml.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(pbo->siml), (void *) pbo, "SIMM"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)pbo, + "bo: init_record Illegal SIML field"); + return(S_db_badField); + } + + /* bo.siol may be a PV_LINK */ + if (pbo->siol.type == PV_LINK){ + status = dbCaAddOutlink(&(pbo->siol), (void *) pbo, "VAL"); + if(status) return(status); + } + if(!(pdset = (struct bodset *)(pbo->dset))) { - recGblRecordError(S_dev_noDSET,pbo,"bo: init_record"); + recGblRecordError(S_dev_noDSET,(void *)pbo,"bo: init_record"); return(S_dev_noDSET); } /* must have write_bo functions defined */ if( (pdset->number < 5) || (pdset->write_bo == NULL) ) { - recGblRecordError(S_dev_missingSup,pbo,"bo: init_record"); + recGblRecordError(S_dev_missingSup,(void *)pbo,"bo: init_record"); return(S_dev_missingSup); } /* get the initial value */ @@ -205,7 +232,7 @@ static long process(pbo) if( (pdset==NULL) || (pdset->write_bo==NULL) ) { pbo->pact=TRUE; - recGblRecordError(S_dev_missingSup,pbo,"write_bo"); + recGblRecordError(S_dev_missingSup,(void *)pbo,"write_bo"); return(S_dev_missingSup); } if (!pbo->pact) { @@ -222,17 +249,47 @@ static long process(pbo) pbo->val = val; pbo->udf = FALSE; }else { - recGblSetSevr(pbo,LINK_ALARM,VALID_ALARM); + recGblSetSevr(pbo,LINK_ALARM,INVALID_ALARM); } } + + /* convert val to rval */ if ( pbo->mask != 0 ) { if(pbo->val==0) pbo->rval = 0; else pbo->rval = pbo->mask; } else pbo->rval = (unsigned long)pbo->val; } - if(status==0) { - status=(*pdset->write_bo)(pbo); /* write the new value */ - } + + /* check for alarms */ + alarm(pbo); + + if (pbo->nsev < INVALID_ALARM ) + status=writeValue(pbo); /* write the new value */ + else { + switch (pbo->ivoa) { + case (IVOA_CONTINUE) : + status=writeValue(pbo); /* write the new value */ + break; + case (IVOA_NO_OUTPUT) : + break; + case (IVOA_OUTPUT_IVOV) : + if(pbo->pact == FALSE){ + /* convert val to rval */ + pbo->val=pbo->ivov; + if ( pbo->mask != 0 ) { + if(pbo->val==0) pbo->rval = 0; + else pbo->rval = pbo->mask; + } else pbo->rval = (unsigned long)pbo->val; + } + status=writeValue(pbo); /* write the new value */ + break; + default : + status=-1; + recGblRecordError(S_db_badField,(void *)pbo, + "ao:process Illegal IVOA field"); + } + } + /* check if device support set pact */ if ( !pact && pbo->pact ) return(0); pbo->pact = TRUE; @@ -246,12 +303,10 @@ static long process(pbo) callbackSetPriority(pbo->prio,pcallback); wdStart(pcallback->wd_id,wait_time,callbackRequest,(int)pcallback); } - /* check for alarms */ - alarm(pbo); /* check event list */ monitor(pbo); /* process the forward scan link record */ - if (pbo->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)pbo->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(pbo); pbo->pact=FALSE; return(status); @@ -316,7 +371,7 @@ static void alarm(pbo) /* check for udf alarm */ if(pbo->udf == TRUE ){ - recGblSetSevr(pbo,UDF_ALARM,VALID_ALARM); + recGblSetSevr(pbo,UDF_ALARM,INVALID_ALARM); } /* check for state alarm */ @@ -374,3 +429,37 @@ static void monitor(pbo) } return; } + +static long writeValue(pbo) + struct boRecord *pbo; +{ + long status; + struct bodset *pdset = (struct bodset *) (pbo->dset); + long nRequest=1; + + if (pbo->pact == TRUE){ + status=(*pdset->write_bo)(pbo); + return(status); + } + + status=recGblGetLinkValue(&(pbo->siml), + (void *)pbo,DBR_ENUM,&(pbo->simm),&nRequest); + if (status) + return(status); + + if (pbo->simm == NO){ + status=(*pdset->write_bo)(pbo); + return(status); + } + if (pbo->simm == YES){ + status=recGblPutLinkValue(&(pbo->siol), + (void *)pbo,DBR_USHORT,&(pbo->val),&nRequest); + } else { + status=-1; + recGblSetSevr(pbo,SOFT_ALARM,INVALID_ALARM); + return(status); + } + recGblSetSevr(pbo,SIMM_ALARM,pbo->sims); + + return(status); +} diff --git a/src/rec/recCalc.c b/src/rec/recCalc.c index e5e533ab5..afccf40c6 100644 --- a/src/rec/recCalc.c +++ b/src/rec/recCalc.c @@ -64,6 +64,10 @@ * .22 02-28-92 jba ANSI C changes * .23 06-02-92 jba changed graphic/control limits for hihi,high,low,lolo * .24 06-16-92 jba Increased dim of rpbuf to hold double constants in expression + * .25 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .26 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .27 07-21-92 jba changed alarm limits for non val related fields + * .28 08-06-92 jba New algorithm for calculating analog alarms */ #include @@ -120,16 +124,12 @@ struct rset calcRSET={ get_control_double, get_alarm_double }; -void alarm(); -void monitor(); -long calcPerform(); -long postfix(); -int fetch_values(); -/* Added for Channel Access Links */ -long dbCaAddInlink(); -long dbCaGetLink(); -#define ARG_MAX 12 +static void alarm(); +static void monitor(); +static int fetch_values(); + +#define ARG_MAX 12 /* Fldnames should have as many as ARG_MAX */ static char Fldnames[ARG_MAX][FLDNAME_SZ] = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"}; @@ -172,7 +172,7 @@ static long process(pcalc) pcalc->pact = TRUE; if(fetch_values(pcalc)==0) { if(calcPerform(&pcalc->a,&pcalc->val,pcalc->rpcl)) { - recGblSetSevr(pcalc,CALC_ALARM,VALID_ALARM); + recGblSetSevr(pcalc,CALC_ALARM,INVALID_ALARM); } else pcalc->udf = FALSE; } tsLocalTime(&pcalc->time); @@ -181,7 +181,7 @@ static long process(pcalc) /* check event list */ monitor(pcalc); /* process the forward scan link record */ - if (pcalc->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)pcalc->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(pcalc); pcalc->pact = FALSE; return(0); } @@ -305,10 +305,12 @@ static long get_alarm_double(paddr,pad) { struct calcRecord *pcalc=(struct calcRecord *)paddr->precord; - pad->upper_alarm_limit = pcalc->hihi; - pad->upper_warning_limit = pcalc->high; - pad->lower_warning_limit = pcalc->low; - pad->lower_alarm_limit = pcalc->lolo; + if(paddr->pfield==(void *)&pcalc->val){ + pad->upper_alarm_limit = pcalc->hihi; + pad->upper_warning_limit = pcalc->high; + pad->lower_warning_limit = pcalc->low; + pad->lower_alarm_limit = pcalc->lolo; + } else recGblGetAlarmDouble(paddr,pad); return(0); } @@ -316,42 +318,45 @@ static long get_alarm_double(paddr,pad) static void alarm(pcalc) struct calcRecord *pcalc; { - double ftemp; - double val=pcalc->val; + double val; + float hyst, lalm, hihi, high, low, lolo; + unsigned short hhsv, llsv, hsv, lsv; - if(pcalc->udf == TRUE ) { - recGblSetSevr(pcalc,UDF_ALARM,VALID_ALARM); + if(pcalc->udf == TRUE ){ + recGblSetSevr(pcalc,UDF_ALARM,INVALID_ALARM); return; } - /* if difference is not > hysterisis use lalm not val */ - ftemp = pcalc->lalm - pcalc->val; - if(ftemp<0.0) ftemp = -ftemp; - if (ftemp < pcalc->hyst) val=pcalc->lalm; + hihi = pcalc->hihi; lolo = pcalc->lolo; high = pcalc->high; low = pcalc->low; + hhsv = pcalc->hhsv; llsv = pcalc->llsv; hsv = pcalc->hsv; lsv = pcalc->lsv; + val = pcalc->val; hyst = pcalc->hyst; lalm = pcalc->lalm; - /* alarm condition hihi */ - if (val > pcalc->hihi && recGblSetSevr(pcalc,HIHI_ALARM,pcalc->hhsv)){ - pcalc->lalm = val; - return; - } + /* alarm condition hihi */ + if (hhsv && (val >= hihi || ((lalm==hihi) && (val >= hihi-hyst)))){ + if (recGblSetSevr(pcalc,HIHI_ALARM,pcalc->hhsv)) pcalc->lalm = hihi; + return; + } - /* alarm condition lolo */ - if (val < pcalc->lolo && recGblSetSevr(pcalc,LOLO_ALARM,pcalc->llsv)){ - pcalc->lalm = val; - return; - } + /* alarm condition lolo */ + if (llsv && (val <= lolo || ((lalm==lolo) && (val <= lolo+hyst)))){ + if (recGblSetSevr(pcalc,LOLO_ALARM,pcalc->llsv)) pcalc->lalm = lolo; + return; + } - /* alarm condition high */ - if (val > pcalc->high && recGblSetSevr(pcalc,HIGH_ALARM,pcalc->hsv)){ - pcalc->lalm = val; - return; - } + /* alarm condition high */ + if (hsv && (val >= high || ((lalm==high) && (val >= high-hyst)))){ + if (recGblSetSevr(pcalc,HIGH_ALARM,pcalc->hsv)) pcalc->lalm = high; + return; + } - /* alarm condition low */ - if (val < pcalc->low && recGblSetSevr(pcalc,LOW_ALARM,pcalc->lsv)){ - pcalc->lalm = val; - return; - } - return; + /* alarm condition low */ + if (lsv && (val <= low || ((lalm==low) && (val <= low+hyst)))){ + if (recGblSetSevr(pcalc,LOW_ALARM,pcalc->lsv)) pcalc->lalm = low; + return; + } + + /* we get here only if val is out of alarm by at least hyst */ + pcalc->lalm = val; + return; } static void monitor(pcalc) @@ -424,7 +429,7 @@ struct calcRecord *pcalc; { if (dbCaGetLink(plink)) { - recGblSetSevr(pcalc,LINK_ALARM,VALID_ALARM); + recGblSetSevr(pcalc,LINK_ALARM,INVALID_ALARM); return(-1); } /* endif */ } @@ -436,7 +441,7 @@ struct calcRecord *pcalc; nRequest=1; status = dbGetLink(&plink->value.db_link,(struct dbCommon *)pcalc,DBR_DOUBLE, pvalue,&options,&nRequest); if(status!=0) { - recGblSetSevr(pcalc,LINK_ALARM,VALID_ALARM); + recGblSetSevr(pcalc,LINK_ALARM,INVALID_ALARM); return(-1); } } /* endif */ diff --git a/src/rec/recCompress.c b/src/rec/recCompress.c index a65e76403..4fc039dc4 100644 --- a/src/rec/recCompress.c +++ b/src/rec/recCompress.c @@ -53,6 +53,8 @@ * .13 02-28-92 jba Changed get_precision,get_graphic_double,get_control_double * .14 02-28-92 jba ANSI C changes * .15 06-02-92 jba changed graphic/control limits for hil,ilil + * .16 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .17 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro */ #include @@ -116,12 +118,13 @@ struct rset compressRSET={ #define compressNTO1AVG 2 #define AVERAGE 3 #define CIRBUF 4 -void alarm(); -void monitor(); -void put_value(); -int compress_array(); -int compress_scalar(); -int array_average(); + +static void monitor(); +static void put_value(); +static int compress_array(); +static int compress_scalar(); +static int array_average(); + static long init_record(pcompress,pass) struct compressRecord *pcompress; @@ -155,7 +158,7 @@ static long process(pcompress) if (pcompress->inp.type != DB_LINK) { status=0; }else if (pcompress->wptr == NULL) { - recGblSetSevr(pcompress,READ_ALARM,VALID_ALARM); + recGblSetSevr(pcompress,READ_ALARM,INVALID_ALARM); status=0; } else { struct dbAddr *pdbAddr = @@ -165,8 +168,8 @@ static long process(pcompress) int alg=pcompress->alg; if(dbGetLink(&pcompress->inp.value.db_link,(struct dbCommon *)pcompress, - DBR_DOUBLE,pcompress->wptr,&options,&no_elements)!=0){ - recGblSetSevr(pcompress,LINK_ALARM,VALID_ALARM); + DBF_DOUBLE,pcompress->wptr,&options,&no_elements)!=0){ + recGblSetSevr(pcompress,LINK_ALARM,INVALID_ALARM); } if(alg==AVERAGE) { @@ -187,10 +190,8 @@ static long process(pcompress) tsLocalTime(&pcompress->time); monitor(pcompress); /* process the forward scan link record */ - if (pcompress->flnk.type==DB_LINK) - dbScanPassive(((struct dbAddr *)pcompress->flnk.value.db_link.pdbAddr)->precord); - } - + recGblFwdLink(pcompress); + } pcompress->pact=FALSE; return(0); } diff --git a/src/rec/recEvent.c b/src/rec/recEvent.c index 6688bf442..83d9a4636 100644 --- a/src/rec/recEvent.c +++ b/src/rec/recEvent.c @@ -33,6 +33,8 @@ * .01 02-28-92 jba ANSI C changes * .02 04-10-92 jba pact now used to test for asyn processing, not status * .03 04-18-92 jba removed process from dev init_record parms + * .04 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .05 08-17-92 jba added simulation mode handling */ #include @@ -97,7 +99,9 @@ struct eventdset { /* event input dset */ DEVSUPFUN get_ioint_info; DEVSUPFUN read_event;/*(0)=> success */ }; -void monitor(); +static void monitor(); +static long readValue(); + static long init_record(pevent,pass) struct eventRecord *pevent; @@ -108,6 +112,40 @@ static long init_record(pevent,pass) if (pass==0) return(0); + /* event.siml must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ + switch (pevent->siml.type) { + case (CONSTANT) : + pevent->simm = pevent->siml.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(pevent->siml), (void *) pevent, "SIMM"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)pevent, + "event: init_record Illegal SIML field"); + return(S_db_badField); + } + + /* event.siol must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ + switch (pevent->siol.type) { + case (CONSTANT) : + pevent->sval = pevent->siol.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(pevent->siol), (void *) pevent, "SVAL"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)pevent, + "event: init_record Illegal SIOL field"); + return(S_db_badField); + } + if( (pdset=(struct eventdset *)(pevent->dset)) && (pdset->init_record) ) status=(*pdset->init_record)(pevent); return(status); @@ -121,7 +159,7 @@ static long process(pevent) unsigned char pact=pevent->pact; if((pdset!=NULL) && (pdset->number >= 5) && pdset->read_event ) - status=(*pdset->read_event)(pevent); /* read the new value */ + status=readValue(pevent); /* read the new value */ /* check if device support set pact */ if ( !pact && pevent->pact ) return(0); pevent->pact = TRUE; @@ -134,7 +172,7 @@ static long process(pevent) monitor(pevent); /* process the forward scan link record */ - if (pevent->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)pevent->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(pevent); pevent->pact=FALSE; return(status); @@ -176,3 +214,42 @@ static void monitor(pevent) db_post_events(pevent,&pevent->val,monitor_mask|DBE_VALUE); return; } + +static long readValue(pevent) + struct eventRecord *pevent; +{ + long status; + struct eventdset *pdset = (struct eventdset *) (pevent->dset); + long nRequest=1; + + if (pevent->pact == TRUE){ + status=(*pdset->read_event)(pevent); + return(status); + } + + status=recGblGetLinkValue(&(pevent->siml), + (void *)pevent,DBR_ENUM,&(pevent->simm),&nRequest); + if (status) + return(status); + + if (pevent->simm == NO){ + status=(*pdset->read_event)(pevent); + return(status); + } + if (pevent->simm == YES){ + status=recGblGetLinkValue(&(pevent->siol), + (void *)pevent,DBR_USHORT,&(pevent->sval),&nRequest); + if (status==0){ + pevent->val=pevent->sval; + pevent->udf=FALSE; + } + status=2; /* dont convert */ + } else { + status=-1; + recGblSetSevr(pevent,SOFT_ALARM,INVALID_ALARM); + return(status); + } + recGblSetSevr(pevent,SIMM_ALARM,pevent->sims); + + return(status); +} diff --git a/src/rec/recFanout.c b/src/rec/recFanout.c index 41215a666..e03915808 100644 --- a/src/rec/recFanout.c +++ b/src/rec/recFanout.c @@ -42,6 +42,8 @@ * .11 02-05-92 jba Changed function arguments from paddr to precord * .12 02-05-92 jba Added FWD scan link * .13 02-28-92 jba ANSI C changes + * .14 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .15 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro */ #include @@ -99,9 +101,6 @@ struct rset fanoutRSET={ #define SELECT_ALL 0 #define SELECTED 1 #define SELECT_MASK 2 -/* Added for Channel Access Links */ -long dbCaAddInlink(); -long dbCaGetLink(); static long init_record(pfanout,pass) @@ -146,14 +145,14 @@ static long process(pfanout) status=dbGetLink(&(pfanout->sell.value.db_link),(struct dbCommon *)pfanout,DBR_USHORT, &(pfanout->seln),&options,&nRequest); if(status!=0) { - recGblSetSevr(pfanout,LINK_ALARM,VALID_ALARM); + recGblSetSevr(pfanout,LINK_ALARM,INVALID_ALARM); } } if (pfanout->sell.type == CA_LINK) { status = dbCaGetLink(&(pfanout->sell)); if(status!=0) { - recGblSetSevr(pfanout,LINK_ALARM,VALID_ALARM); + recGblSetSevr(pfanout,LINK_ALARM,INVALID_ALARM); } } @@ -174,7 +173,7 @@ static long process(pfanout) break; case (SELECTED): if(pfanout->seln<0 || pfanout->seln>6) { - recGblSetSevr(pfanout,SOFT_ALARM,VALID_ALARM); + recGblSetSevr(pfanout,SOFT_ALARM,INVALID_ALARM); break; } if(pfanout->seln==0) { @@ -189,7 +188,7 @@ static long process(pfanout) break; } if(pfanout->seln<0 || pfanout->seln>63 ) { - recGblSetSevr(pfanout,SOFT_ALARM,VALID_ALARM); + recGblSetSevr(pfanout,SOFT_ALARM,INVALID_ALARM); break; } plink=&(pfanout->lnk1); @@ -200,7 +199,7 @@ static long process(pfanout) } break; default: - recGblSetSevr(pfanout,SOFT_ALARM,VALID_ALARM); + recGblSetSevr(pfanout,SOFT_ALARM,INVALID_ALARM); } pfanout->udf=FALSE; tsLocalTime(&pfanout->time); @@ -212,8 +211,7 @@ static long process(pfanout) db_post_events(pfanout,&pfanout->sevr,DBE_VALUE); } /* process the forward scan link record */ - if (pfanout->flnk.type==DB_LINK) - dbScanPassive(((struct dbAddr *)pfanout->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(pfanout); pfanout->pact=FALSE; return(0); diff --git a/src/rec/recHistogram.c b/src/rec/recHistogram.c index 07ce9638f..d60756075 100644 --- a/src/rec/recHistogram.c +++ b/src/rec/recHistogram.c @@ -34,6 +34,9 @@ * .03 02-28-92 jba ANSI C changes * .04 04-10-92 jba pact now used to test for asyn processing, not status * .05 04-18-92 jba removed process from dev init_record parms + * .06 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .07 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .08 08-13-92 jba Added simulation processing */ #include @@ -116,12 +119,14 @@ struct callback { void (*process)(); }; +/* void callbackRequest(); -void monitor(); +*/ -void convert(); -long add_count(); -long clear_histogram(); +static long add_count(); +static long clear_histogram(); +static void monitor(); +static long readValue(); static void wdCallback(pcallback) struct callback *pcallback; @@ -155,7 +160,7 @@ static long init_record(phistogram,pass) long status; struct callback *pcallback=(struct callback *)(phistogram->wdog); float wait_time; - void (*process)(); + void (*process)()=NULL; if (pass==0){ @@ -189,14 +194,48 @@ static long init_record(phistogram,pass) wdStart(pcallback->wd_id,wait_time,callbackRequest,(int)pcallback); } + /* histogram.siml must be a CONSTANT or a PV_LINK or a DB_LINK */ + switch (phistogram->siml.type) { + case (CONSTANT) : + phistogram->simm = phistogram->siml.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(phistogram->siml), (void *) phistogram, "SIMM"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)phistogram, + "histogram: init_record Illegal SIML field"); + return(S_db_badField); + } + + /* histogram.siol must be a CONSTANT or a PV_LINK or a DB_LINK */ + switch (phistogram->siol.type) { + case (CONSTANT) : + phistogram->sval = phistogram->siol.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(phistogram->siol), (void *) phistogram, "SVAL"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)phistogram, + "histogram: init_record Illegal SIOL field"); + return(S_db_badField); + } + /* must have device support defined */ if(!(pdset = (struct histogramdset *)(phistogram->dset))) { - recGblRecordError(S_dev_noDSET,phistogram,"histogram: init_record"); + recGblRecordError(S_dev_noDSET,(void *)phistogram,"histogram: init_record"); return(S_dev_noDSET); } /* must have read_histogram function defined */ if( (pdset->number < 6) || (pdset->read_histogram == NULL) ) { - recGblRecordError(S_dev_missingSup,phistogram,"histogram: init_record"); + recGblRecordError(S_dev_missingSup,(void *)phistogram,"histogram: init_record"); return(S_dev_missingSup); } /* call device support init_record */ @@ -215,11 +254,11 @@ static long process(phistogram) if( (pdset==NULL) || (pdset->read_histogram==NULL) ) { phistogram->pact=TRUE; - recGblRecordError(S_dev_missingSup,phistogram,"read_histogram"); + recGblRecordError(S_dev_missingSup,(void *)phistogram,"read_histogram"); return(S_dev_missingSup); } - status=(*pdset->read_histogram)(phistogram); + status=readValue(phistogram); /* read the new value */ /* check if device support set pact */ if ( !pact && phistogram->pact ) return(0); phistogram->pact = TRUE; @@ -233,7 +272,7 @@ static long process(phistogram) monitor(phistogram); /* process the forward scan link record */ - if (phistogram->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)phistogram->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(phistogram); phistogram->pact=FALSE; return(status); @@ -362,9 +401,9 @@ static long add_count(phistogram) if(phistogram->csta==FALSE) return(0); if(phistogram->llim >= phistogram->ulim) { - if (phistogram->nsevnsevstat = SOFT_ALARM; - phistogram->sevr = VALID_ALARM; + phistogram->sevr = INVALID_ALARM; return(-1); } } @@ -394,3 +433,40 @@ static long clear_histogram(phistogram) return(0); } + +static long readValue(phistogram) + struct histogramRecord *phistogram; +{ + long status; + struct histogramdset *pdset = (struct histogramdset *) (phistogram->dset); + long nRequest=1; + + if (phistogram->pact == TRUE){ + status=(*pdset->read_histogram)(phistogram); + return(status); + } + + status=recGblGetLinkValue(&(phistogram->siml), + (void *)phistogram,DBR_ENUM,&(phistogram->simm),&nRequest); + if (status) + return(status); + + if (phistogram->simm == NO){ + status=(*pdset->read_histogram)(phistogram); + return(status); + } + if (phistogram->simm == YES){ + status=recGblGetLinkValue(&(phistogram->siol), + (void *)phistogram,DBR_DOUBLE,&(phistogram->sval),&nRequest); + if (status==0){ + phistogram->sgnl=phistogram->sval; + } + } else { + status=-1; + recGblSetSevr(phistogram,SOFT_ALARM,INVALID_ALARM); + return(status); + } + recGblSetSevr(phistogram,SIMM_ALARM,phistogram->sims); + + return(status); +} diff --git a/src/rec/recLongin.c b/src/rec/recLongin.c index 3dbf8eb89..338fb78b7 100644 --- a/src/rec/recLongin.c +++ b/src/rec/recLongin.c @@ -36,6 +36,11 @@ * .05 04-10-92 jba pact now used to test for asyn processing, not status * .06 04-18-92 jba removed process from dev init_record parms * .07 06-02-92 jba changed graphic/control limits for hihi,high,low,lolo + * .08 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .09 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .10 07-21-92 jba changed alarm limits for non val related fields + * .11 08-06-92 jba New algorithm for calculating analog alarms + * .12 08-13-92 jba Added simulation processing */ @@ -102,8 +107,10 @@ struct longindset { /* longin input dset */ DEVSUPFUN get_ioint_info; DEVSUPFUN read_longin; /*returns: (-1,0)=>(failure,success)*/ }; -void alarm(); -void monitor(); +static void alarm(); +static void monitor(); +static long readValue(); + static long init_record(plongin,pass) struct longinRecord *plongin; @@ -114,13 +121,47 @@ static long init_record(plongin,pass) if (pass==0) return(0); + /* longin.siml must be a CONSTANT or a PV_LINK or a DB_LINK */ + switch (plongin->siml.type) { + case (CONSTANT) : + plongin->simm = plongin->siml.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(plongin->siml), (void *) plongin, "SIMM"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)plongin, + "longin: init_record Illegal SIML field"); + return(S_db_badField); + } + + /* longin.siol must be a CONSTANT or a PV_LINK or a DB_LINK */ + switch (plongin->siol.type) { + case (CONSTANT) : + plongin->sval = plongin->siol.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(plongin->siol), (void *) plongin, "SVAL"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)plongin, + "longin: init_record Illegal SIOL field"); + return(S_db_badField); + } + if(!(pdset = (struct longindset *)(plongin->dset))) { - recGblRecordError(S_dev_noDSET,plongin,"longin: init_record"); + recGblRecordError(S_dev_noDSET,(void *)plongin,"longin: init_record"); return(S_dev_noDSET); } /* must have read_longin function defined */ if( (pdset->number < 5) || (pdset->read_longin == NULL) ) { - recGblRecordError(S_dev_missingSup,plongin,"longin: init_record"); + recGblRecordError(S_dev_missingSup,(void *)plongin,"longin: init_record"); return(S_dev_missingSup); } if( pdset->init_record ) { @@ -138,11 +179,11 @@ static long process(plongin) if( (pdset==NULL) || (pdset->read_longin==NULL) ) { plongin->pact=TRUE; - recGblRecordError(S_dev_missingSup,plongin,"read_longin"); + recGblRecordError(S_dev_missingSup,(void *)plongin,"read_longin"); return(S_dev_missingSup); } - status=(*pdset->read_longin)(plongin); /* read the new value */ + status=readValue(plongin); /* read the new value */ /* check if device support set pact */ if ( !pact && plongin->pact ) return(0); plongin->pact = TRUE; @@ -153,9 +194,8 @@ static long process(plongin) alarm(plongin); /* check event list */ monitor(plongin); - /* process the forward scan link record */ - if (plongin->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)plongin->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(plongin); plongin->pact=FALSE; return(status); @@ -223,52 +263,57 @@ static long get_alarm_double(paddr,pad) { struct longinRecord *plongin=(struct longinRecord *)paddr->precord; - pad->upper_alarm_limit = plongin->hihi; - pad->upper_warning_limit = plongin->high; - pad->lower_warning_limit = plongin->low; - pad->lower_alarm_limit = plongin->lolo; + if(paddr->pfield==(void *)&plongin->val){ + pad->upper_alarm_limit = plongin->hihi; + pad->upper_warning_limit = plongin->high; + pad->lower_warning_limit = plongin->low; + pad->lower_alarm_limit = plongin->lolo; + } else recGblGetAlarmDouble(paddr,pad); return(0); } static void alarm(plongin) struct longinRecord *plongin; { - long ftemp; - long val=plongin->val; + double val; + float hyst, lalm, hihi, high, low, lolo; + unsigned short hhsv, llsv, hsv, lsv; if(plongin->udf == TRUE ){ - recGblSetSevr(plongin,UDF_ALARM,VALID_ALARM); + recGblSetSevr(plongin,UDF_ALARM,INVALID_ALARM); return; } - /* if difference is not > hysterisis use lalm not val */ - ftemp = plongin->lalm - plongin->val; - if(ftemp<0) ftemp = -ftemp; - if (ftemp < plongin->hyst) val=plongin->lalm; + hihi = plongin->hihi; lolo = plongin->lolo; high = plongin->high; low = plongin->low; + hhsv = plongin->hhsv; llsv = plongin->llsv; hsv = plongin->hsv; lsv = plongin->lsv; + val = plongin->val; hyst = plongin->hyst; lalm = plongin->lalm; - /* alarm condition hihi */ - if (val > plongin->hihi && recGblSetSevr(plongin,HIHI_ALARM,plongin->hhsv)){ - plongin->lalm = val; - return; - } + /* alarm condition hihi */ + if (hhsv && (val >= hihi || ((lalm==hihi) && (val >= hihi-hyst)))){ + if (recGblSetSevr(plongin,HIHI_ALARM,plongin->hhsv)) plongin->lalm = hihi; + return; + } - /* alarm condition lolo */ - if (val < plongin->lolo && recGblSetSevr(plongin,LOLO_ALARM,plongin->llsv)){ - plongin->lalm = val; - return; - } + /* alarm condition lolo */ + if (llsv && (val <= lolo || ((lalm==lolo) && (val <= lolo+hyst)))){ + if (recGblSetSevr(plongin,LOLO_ALARM,plongin->llsv)) plongin->lalm = lolo; + return; + } - /* alarm condition high */ - if (val > plongin->high && recGblSetSevr(plongin,HIGH_ALARM,plongin->hsv)){ - plongin->lalm = val; - return; - } + /* alarm condition high */ + if (hsv && (val >= high || ((lalm==high) && (val >= high-hyst)))){ + if (recGblSetSevr(plongin,HIGH_ALARM,plongin->hsv)) plongin->lalm = high; + return; + } - /* alarm condition low */ - if (val < plongin->low && recGblSetSevr(plongin,LOW_ALARM,plongin->lsv)){ - plongin->lalm = val; - return; - } - return; + /* alarm condition low */ + if (lsv && (val <= low || ((lalm==low) && (val <= low+hyst)))){ + if (recGblSetSevr(plongin,LOW_ALARM,plongin->lsv)) plongin->lalm = low; + return; + } + + /* we get here only if val is out of alarm by at least hyst */ + plongin->lalm = val; + return; } static void monitor(plongin) @@ -318,3 +363,41 @@ static void monitor(plongin) } return; } + +static long readValue(plongin) + struct longinRecord *plongin; +{ + long status; + struct longindset *pdset = (struct longindset *) (plongin->dset); + long nRequest=1; + + if (plongin->pact == TRUE){ + status=(*pdset->read_longin)(plongin); + return(status); + } + + status=recGblGetLinkValue(&(plongin->siml), + (void *)plongin,DBR_ENUM,&(plongin->simm),&nRequest); + if (status) + return(status); + + if (plongin->simm == NO){ + status=(*pdset->read_longin)(plongin); + return(status); + } + if (plongin->simm == YES){ + status=recGblGetLinkValue(&(plongin->siol), + (void *)plongin,DBR_LONG,&(plongin->sval),&nRequest); + if (status==0){ + plongin->val=plongin->sval; + plongin->udf=FALSE; + } + } else { + status=-1; + recGblSetSevr(plongin,SOFT_ALARM,INVALID_ALARM); + return(status); + } + recGblSetSevr(plongin,SIMM_ALARM,plongin->sims); + + return(status); +} diff --git a/src/rec/recLongout.c b/src/rec/recLongout.c index 6f91d74dd..84c46a405 100644 --- a/src/rec/recLongout.c +++ b/src/rec/recLongout.c @@ -35,6 +35,12 @@ * .04 04-10-92 jba pact now used to test for asyn processing, not status * .05 04-18-92 jba removed process from dev init_record parms * .06 06-02-92 jba changed graphic/control limits for hihi,high,low,lolo + * .07 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .08 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .09 07-21-92 jba changed alarm limits for non val related fields + * .10 08-06-92 jba New algorithm for calculating analog alarms + * .11 08-14-92 jba Added simulation processing + * .12 08-19-92 jba Added code for invalid alarm output action */ @@ -101,12 +107,9 @@ struct longoutdset { /* longout input dset */ DEVSUPFUN get_ioint_info; DEVSUPFUN write_longout;/*(-1,0)=>(failure,success*/ }; -void alarm(); -int convert(); -void monitor(); -/* Added for Channel Access Links */ -long dbCaAddInlink(); -long dbCaGetLink(); +static void alarm(); +static void monitor(); +static long writeValue(); static long init_record(plongout,pass) @@ -118,13 +121,36 @@ static long init_record(plongout,pass) if (pass==0) return(0); + /* longout.siml must be a CONSTANT or a PV_LINK or a DB_LINK */ + switch (plongout->siml.type) { + case (CONSTANT) : + plongout->simm = plongout->siml.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(plongout->siml), (void *) plongout, "SIMM"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)plongout, + "longout: init_record Illegal SIML field"); + return(S_db_badField); + } + + /* longout.siol may be a PV_LINK */ + if (plongout->siol.type == PV_LINK){ + status = dbCaAddOutlink(&(plongout->siol), (void *) plongout, "VAL"); + if(status) return(status); + } + if(!(pdset = (struct longoutdset *)(plongout->dset))) { - recGblRecordError(S_dev_noDSET,plongout,"longout: init_record"); + recGblRecordError(S_dev_noDSET,(void *)plongout,"longout: init_record"); return(S_dev_noDSET); } /* must have write_longout functions defined */ if( (pdset->number < 5) || (pdset->write_longout == NULL) ) { - recGblRecordError(S_dev_missingSup,plongout,"longout: init_record"); + recGblRecordError(S_dev_missingSup,(void *)plongout,"longout: init_record"); return(S_dev_missingSup); } /* get the initial value dol is a constant*/ @@ -153,7 +179,7 @@ static long process(plongout) if( (pdset==NULL) || (pdset->write_longout==NULL) ) { plongout->pact=TRUE; - recGblRecordError(S_dev_missingSup,plongout,"write_longout"); + recGblRecordError(S_dev_missingSup,(void *)plongout,"write_longout"); return(S_dev_missingSup); } if (!plongout->pact) { @@ -166,7 +192,7 @@ static long process(plongout) DBR_LONG,&plongout->val,&options,&nRequest); plongout->pact = FALSE; if(status!=0){ - recGblSetSevr(plongout,LINK_ALARM,VALID_ALARM); + recGblSetSevr(plongout,LINK_ALARM,INVALID_ALARM); } else plongout->udf=FALSE; } if((plongout->dol.type == CA_LINK) && (plongout->omsl == CLOSED_LOOP)){ @@ -174,14 +200,36 @@ static long process(plongout) status = dbCaGetLink(&(plongout->dol)); plongout->pact = FALSE; if(status!=0){ - recGblSetSevr(plongout,LINK_ALARM,VALID_ALARM); + recGblSetSevr(plongout,LINK_ALARM,INVALID_ALARM); } else plongout->udf=FALSE; } } - if(status==0) { - status=(*pdset->write_longout)(plongout); /* write the new value */ - } + /* check for alarms */ + alarm(plongout); + + if (plongout->nsev < INVALID_ALARM ) + status=writeValue(plongout); /* write the new value */ + else { + switch (plongout->ivoa) { + case (IVOA_CONTINUE) : + status=writeValue(plongout); /* write the new value */ + break; + case (IVOA_NO_OUTPUT) : + break; + case (IVOA_OUTPUT_IVOV) : + if(plongout->pact == FALSE){ + plongout->val=plongout->ivov; + } + status=writeValue(plongout); /* write the new value */ + break; + default : + status=-1; + recGblRecordError(S_db_badField,(void *)plongout, + "ao:process Illegal IVOA field"); + } + } + /* check if device support set pact */ if ( !pact && plongout->pact ) return(0); plongout->pact = TRUE; @@ -194,7 +242,7 @@ static long process(plongout) monitor(plongout); /* process the forward scan link record */ - if (plongout->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)plongout->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(plongout); plongout->pact=FALSE; return(status); @@ -259,54 +307,57 @@ static long get_alarm_double(paddr,pad) { struct longoutRecord *plongout=(struct longoutRecord *)paddr->precord; - pad->upper_alarm_limit = plongout->hihi; - pad->upper_warning_limit = plongout->high; - pad->lower_warning_limit = plongout->low; - pad->lower_alarm_limit = plongout->lolo; + if(paddr->pfield==(void *)&plongout->val){ + pad->upper_alarm_limit = plongout->hihi; + pad->upper_warning_limit = plongout->high; + pad->lower_warning_limit = plongout->low; + pad->lower_alarm_limit = plongout->lolo; + } else recGblGetAlarmDouble(paddr,pad); return(0); } - static void alarm(plongout) struct longoutRecord *plongout; { - long ftemp; - long val=plongout->val; + double val; + float hyst, lalm, hihi, high, low, lolo; + unsigned short hhsv, llsv, hsv, lsv; - if(plongout->udf == TRUE ){ - recGblSetSevr(plongout,UDF_ALARM,VALID_ALARM); - return; - } + if(plongout->udf == TRUE ){ + recGblSetSevr(plongout,UDF_ALARM,INVALID_ALARM); + return; + } + hihi = plongout->hihi; lolo = plongout->lolo; high = plongout->high; low = plongout->low; + hhsv = plongout->hhsv; llsv = plongout->llsv; hsv = plongout->hsv; lsv = plongout->lsv; + val = plongout->val; hyst = plongout->hyst; lalm = plongout->lalm; - /* if difference is not > hysterisis use lalm not val */ - ftemp = plongout->lalm - plongout->val; - if(ftemp<0) ftemp = -ftemp; - if (ftemp < plongout->hyst) val=plongout->lalm; + /* alarm condition hihi */ + if (hhsv && (val >= hihi || ((lalm==hihi) && (val >= hihi-hyst)))){ + if (recGblSetSevr(plongout,HIHI_ALARM,plongout->hhsv)) plongout->lalm = hihi; + return; + } - /* alarm condition hihi */ - if (val > plongout->hihi && recGblSetSevr(plongout,HIHI_ALARM,plongout->hhsv)){ - plongout->lalm = val; - return; - } + /* alarm condition lolo */ + if (llsv && (val <= lolo || ((lalm==lolo) && (val <= lolo+hyst)))){ + if (recGblSetSevr(plongout,LOLO_ALARM,plongout->llsv)) plongout->lalm = lolo; + return; + } - /* alarm condition lolo */ - if (val < plongout->lolo && recGblSetSevr(plongout,LOLO_ALARM,plongout->llsv)){ - plongout->lalm = val; - return; - } + /* alarm condition high */ + if (hsv && (val >= high || ((lalm==high) && (val >= high-hyst)))){ + if (recGblSetSevr(plongout,HIGH_ALARM,plongout->hsv)) plongout->lalm = high; + return; + } - /* alarm condition high */ - if (val > plongout->high && recGblSetSevr(plongout,HIGH_ALARM,plongout->hsv)){ - plongout->lalm = val; - return; - } + /* alarm condition low */ + if (lsv && (val <= low || ((lalm==low) && (val <= low+hyst)))){ + if (recGblSetSevr(plongout,LOW_ALARM,plongout->lsv)) plongout->lalm = low; + return; + } - /* alarm condition low */ - if (val < plongout->low && recGblSetSevr(plongout,LOW_ALARM,plongout->lsv)){ - plongout->lalm = val; - return; - } - return; + /* we get here only if val is out of alarm by at least hyst */ + plongout->lalm = val; + return; } static void monitor(plongout) @@ -356,3 +407,37 @@ static void monitor(plongout) } return; } + +static long writeValue(plongout) + struct longoutRecord *plongout; +{ + long status; + struct longoutdset *pdset = (struct longoutdset *) (plongout->dset); + long nRequest=1; + + if (plongout->pact == TRUE){ + status=(*pdset->write_longout)(plongout); + return(status); + } + + status=recGblGetLinkValue(&(plongout->siml), + (void *)plongout,DBR_ENUM,&(plongout->simm),&nRequest); + if (status) + return(status); + + if (plongout->simm == NO){ + status=(*pdset->write_longout)(plongout); + return(status); + } + if (plongout->simm == YES){ + status=recGblPutLinkValue(&(plongout->siol), + (void *)plongout,DBR_LONG,&(plongout->val),&nRequest); + } else { + status=-1; + recGblSetSevr(plongout,SOFT_ALARM,INVALID_ALARM); + return(status); + } + recGblSetSevr(plongout,SIMM_ALARM,plongout->sims); + + return(status); +} diff --git a/src/rec/recMbbi.c b/src/rec/recMbbi.c index 25a5507da..d33bcbf18 100644 --- a/src/rec/recMbbi.c +++ b/src/rec/recMbbi.c @@ -51,6 +51,9 @@ * .16 02-28-92 jba ANSI C changes * .17 04-10-92 jba pact now used to test for asyn processing, not status * .18 04-18-92 jba removed process from dev dev init_record parms + * .19 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .20 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .21 08-14-92 jba Added simulation processing */ #include @@ -115,8 +118,10 @@ struct mbbidset { /* multi bit binary input dset */ DEVSUPFUN get_ioint_info; DEVSUPFUN read_mbbi;/*(0,2)=>(success, success no convert)*/ }; -void alarm(); -void monitor(); +static void alarm(); +static void monitor(); +static long readValue(); + static void init_common(pmbbi) struct mbbiRecord *pmbbi; @@ -146,13 +151,47 @@ static long init_record(pmbbi,pass) if (pass==0) return(0); + /* mbbi.siml must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ + switch (pmbbi->siml.type) { + case (CONSTANT) : + pmbbi->simm = pmbbi->siml.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(pmbbi->siml), (void *) pmbbi, "SIMM"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)pmbbi, + "mbbi: init_record Illegal SIML field"); + return(S_db_badField); + } + + /* mbbi.siol must be a CONSTANT or a PV_LINK or a DB_LINK or a CA_LINK*/ + switch (pmbbi->siol.type) { + case (CONSTANT) : + pmbbi->sval = pmbbi->siol.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(pmbbi->siol), (void *) pmbbi, "SVAL"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)pmbbi, + "mbbi: init_record Illegal SIOL field"); + return(S_db_badField); + } + if(!(pdset = (struct mbbidset *)(pmbbi->dset))) { - recGblRecordError(S_dev_noDSET,pmbbi,"mbbi: init_record"); + recGblRecordError(S_dev_noDSET,(void *)pmbbi,"mbbi: init_record"); return(S_dev_noDSET); } /* must have read_mbbi function defined */ if( (pdset->number < 5) || (pdset->read_mbbi == NULL) ) { - recGblRecordError(S_dev_missingSup,pmbbi,"mbbi: init_record"); + recGblRecordError(S_dev_missingSup,(void *)pmbbi,"mbbi: init_record"); return(S_dev_missingSup); } /* initialize mask*/ @@ -177,11 +216,11 @@ static long process(pmbbi) if( (pdset==NULL) || (pdset->read_mbbi==NULL) ) { pmbbi->pact=TRUE; - recGblRecordError(S_dev_missingSup,pmbbi,"read_mbbi"); + recGblRecordError(S_dev_missingSup,(void *)pmbbi,"read_mbbi"); return(S_dev_missingSup); } - status=(*pdset->read_mbbi)(pmbbi); /* read the new value */ + status=readValue(pmbbi); /* read the new value */ /* check if device support set pact */ if ( !pact && pmbbi->pact ) return(0); pmbbi->pact = TRUE; @@ -216,12 +255,11 @@ static long process(pmbbi) /* check for alarms */ alarm(pmbbi); - /* check event list */ monitor(pmbbi); /* process the forward scan link record */ - if (pmbbi->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)pmbbi->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(pmbbi); pmbbi->pact=FALSE; return(status); @@ -321,7 +359,7 @@ static void alarm(pmbbi) /* check for udf alarm */ if(pmbbi->udf == TRUE ){ - recGblSetSevr(pmbbi,UDF_ALARM,VALID_ALARM); + recGblSetSevr(pmbbi,UDF_ALARM,INVALID_ALARM); } /* check for state alarm */ @@ -376,3 +414,42 @@ static void monitor(pmbbi) } return; } + +static long readValue(pmbbi) + struct mbbiRecord *pmbbi; +{ + long status; + struct mbbidset *pdset = (struct mbbidset *) (pmbbi->dset); + long nRequest=1; + + if (pmbbi->pact == TRUE){ + status=(*pdset->read_mbbi)(pmbbi); + return(status); + } + + status=recGblGetLinkValue(&(pmbbi->siml), + (void *)pmbbi,DBR_ENUM,&(pmbbi->simm),&nRequest); + if (status) + return(status); + + if (pmbbi->simm == NO){ + status=(*pdset->read_mbbi)(pmbbi); + return(status); + } + if (pmbbi->simm == YES){ + status=recGblGetLinkValue(&(pmbbi->siol), + (void *)pmbbi,DBR_USHORT,&(pmbbi->sval),&nRequest); + if (status==0){ + pmbbi->val=pmbbi->sval; + pmbbi->udf=FALSE; + } + status=2; /* dont convert */ + } else { + status=-1; + recGblSetSevr(pmbbi,SOFT_ALARM,INVALID_ALARM); + return(status); + } + recGblSetSevr(pmbbi,SIMM_ALARM,pmbbi->sims); + + return(status); +} diff --git a/src/rec/recMbbo.c b/src/rec/recMbbo.c index b4c1d950c..074455925 100644 --- a/src/rec/recMbbo.c +++ b/src/rec/recMbbo.c @@ -54,6 +54,10 @@ * .19 02-28-92 jba ANSI C changes * .20 04-10-92 jba pact now used to test for asyn processing, not status * .21 04-18-92 jba removed process from dev init_record parms + * .22 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .23 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .24 08-14-92 jba Added simulation processing + * .25 08-19-92 jba Added code for invalid alarm output action */ #include @@ -121,8 +125,10 @@ struct mbbodset { /* multi bit binary output dset */ }; -void alarm(); -void monitor(); +static void alarm(); +static void convert(); +static void monitor(); +static long writeValue(); static void init_common(pmbbo) @@ -153,13 +159,36 @@ static long init_record(pmbbo,pass) if (pass==0) return(0); + /* mbbo.siml must be a CONSTANT or a PV_LINK or a DB_LINK */ + switch (pmbbo->siml.type) { + case (CONSTANT) : + pmbbo->simm = pmbbo->siml.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(pmbbo->siml), (void *) pmbbo, "SIMM"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)pmbbo, + "mbbo: init_record Illegal SIML field"); + return(S_db_badField); + } + + /* mbbo.siol may be a PV_LINK */ + if (pmbbo->siol.type == PV_LINK){ + status = dbCaAddOutlink(&(pmbbo->siol), (void *) pmbbo, "VAL"); + if(status) return(status); + } + if(!(pdset = (struct mbbodset *)(pmbbo->dset))) { - recGblRecordError(S_dev_noDSET,pmbbo,"mbbo: init_record"); + recGblRecordError(S_dev_noDSET,(void *)pmbbo,"mbbo: init_record"); return(S_dev_noDSET); } /* must have write_mbbo function defined */ if( (pdset->number < 5) || (pdset->write_mbbo == NULL) ) { - recGblRecordError(S_dev_missingSup,pmbbo,"mbbo: init_record"); + recGblRecordError(S_dev_missingSup,(void *)pmbbo,"mbbo: init_record"); return(S_dev_missingSup); } if (pmbbo->dol.type == CONSTANT){ @@ -214,7 +243,7 @@ static long process(pmbbo) if( (pdset==NULL) || (pdset->write_mbbo==NULL) ) { pmbbo->pact=TRUE; - recGblRecordError(S_dev_missingSup,pmbbo,"write_mbbo"); + recGblRecordError(S_dev_missingSup,(void *)pmbbo,"write_mbbo"); return(S_dev_missingSup); } @@ -233,40 +262,54 @@ static long process(pmbbo) pmbbo->val= val; pmbbo->udf= FALSE; } else { - recGblSetSevr(pmbbo,LINK_ALARM,VALID_ALARM); - goto DONT_WRITE; + recGblSetSevr(pmbbo,LINK_ALARM,INVALID_ALARM); + goto CONTINUE; } } if(pmbbo->udf==TRUE) { - recGblSetSevr(pmbbo,UDF_ALARM,VALID_ALARM); - goto DONT_WRITE; + recGblSetSevr(pmbbo,UDF_ALARM,INVALID_ALARM); + goto CONTINUE; } - if(pmbbo->sdef) { - unsigned long *pvalues = &(pmbbo->zrvl); - - if(pmbbo->val>15) { - recGblSetSevr(pmbbo,SOFT_ALARM,VALID_ALARM); - goto DONT_WRITE; - } - pmbbo->rval = pvalues[pmbbo->val]; - } else pmbbo->rval = (unsigned long)(pmbbo->val); - if(pmbbo->shft>0) pmbbo->rval <<= pmbbo->shft; + /* convert val to rval */ + convert(pmbbo); + } + +CONTINUE: + /* check for alarms */ + alarm(pmbbo); + + if (pmbbo->nsev < INVALID_ALARM ) + status=writeValue(pmbbo); /* write the new value */ + else { + switch (pmbbo->ivoa) { + case (IVOA_CONTINUE) : + status=writeValue(pmbbo); /* write the new value */ + break; + case (IVOA_NO_OUTPUT) : + break; + case (IVOA_OUTPUT_IVOV) : + if (pmbbo->pact == FALSE){ + pmbbo->val=pmbbo->ivov; + convert(pmbbo); + } + status=writeValue(pmbbo); /* write the new value */ + break; + default : + status=-1; + recGblRecordError(S_db_badField,(void *)pmbbo, + "ao:process Illegal IVOA field"); + } } - status=(*pdset->write_mbbo)(pmbbo); /* write the new value */ -DONT_WRITE: /* check if device support set pact */ if ( !pact && pmbbo->pact ) return(0); pmbbo->pact = TRUE; tsLocalTime(&pmbbo->time); - /* check for alarms */ - alarm(pmbbo); /* check event list */ monitor(pmbbo); /* process the forward scan link record */ - if(pmbbo->flnk.type==DB_LINK) - dbScanPassive(((struct dbAddr *)pmbbo->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(pmbbo); pmbbo->pact=FALSE; return(status); } @@ -421,3 +464,58 @@ static void monitor(pmbbo) } return; } + +static void convert(pmbbo) + struct mbboRecord *pmbbo; +{ + unsigned long *pvalues = &(pmbbo->zrvl); + + /* convert val to rval */ + if(pmbbo->sdef) { + + if(pmbbo->val>15) { + recGblSetSevr(pmbbo,SOFT_ALARM,INVALID_ALARM); + return; + } + pmbbo->rval = pvalues[pmbbo->val]; + } else pmbbo->rval = (unsigned long)(pmbbo->val); + if(pmbbo->shft>0) pmbbo->rval <<= pmbbo->shft; + + return; +} + + + +static long writeValue(pmbbo) + struct mbboRecord *pmbbo; +{ + long status; + struct mbbodset *pdset = (struct mbbodset *) (pmbbo->dset); + long nRequest=1; + + if (pmbbo->pact == TRUE){ + status=(*pdset->write_mbbo)(pmbbo); + return(status); + } + + status=recGblGetLinkValue(&(pmbbo->siml), + (void *)pmbbo,DBR_ENUM,&(pmbbo->simm),&nRequest); + if (status) + return(status); + + if (pmbbo->simm == NO){ + status=(*pdset->write_mbbo)(pmbbo); + return(status); + } + if (pmbbo->simm == YES){ + status=recGblPutLinkValue(&(pmbbo->siol), + (void *)pmbbo,DBR_USHORT,&(pmbbo->val),&nRequest); + } else { + status=-1; + recGblSetSevr(pmbbo,SOFT_ALARM,INVALID_ALARM); + return(status); + } + recGblSetSevr(pmbbo,SIMM_ALARM,pmbbo->sims); + + return(status); +} diff --git a/src/rec/recPermissive.c b/src/rec/recPermissive.c index c98b144fc..06fa73baf 100644 --- a/src/rec/recPermissive.c +++ b/src/rec/recPermissive.c @@ -34,6 +34,7 @@ * .02 11-11-91 jba Moved set and reset of alarm stat and sevr to macros * .03 02-05-92 jba Changed function arguments from paddr to precord * .04 02-28-92 jba ANSI C changes + * .05 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro */ #include @@ -87,7 +88,7 @@ struct rset permissiveRSET={ get_control_double, get_alarm_double }; -void monitor(); +static void monitor(); static long process(ppermissive) struct permissiveRecord *ppermissive; @@ -97,8 +98,7 @@ static long process(ppermissive) ppermissive->udf=FALSE; tsLocalTime(&ppermissive->time); monitor(ppermissive); - if (ppermissive->flnk.type==DB_LINK) - dbScanPassive(((struct dbAddr *)ppermissive->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(ppermissive); ppermissive->pact=FALSE; return(0); } diff --git a/src/rec/recPid.c b/src/rec/recPid.c index dd9f2db13..1b229885a 100644 --- a/src/rec/recPid.c +++ b/src/rec/recPid.c @@ -36,6 +36,10 @@ * .04 02-28-92 jba Changed get_precision,get_graphic_double,get_control_double * .05 02-28-92 jba ANSI C changes * .06 06-02-92 jba changed graphic/control limits for hihi,high,low,lolo + * .07 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .08 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .09 07-21-92 jba changed alarm limits for non val related fields + * .10 08-06-92 jba New algorithm for calculating analog alarms */ #include @@ -94,12 +98,9 @@ struct rset pidRSET={ get_alarm_double }; -void alarm(); -void monitor(); -long do_pid(); -/* Added for Channel Access Links */ -long dbCaAddInlink(); -long dbCaGetLink(); +static void alarm(); +static void monitor(); +static long do_pid(); static long init_record(ppid,pass) @@ -146,7 +147,7 @@ static long process(ppid) monitor(ppid); /* process the forward scan link record */ - if (ppid->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)ppid->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(ppid); ppid->pact=FALSE; return(status); @@ -233,49 +234,57 @@ static long get_alarm_double(paddr,pad) { struct pidRecord *ppid=(struct pidRecord *)paddr->precord; - pad->upper_alarm_limit = ppid->hihi; - pad->upper_warning_limit = ppid->high; - pad->lower_warning_limit = ppid->low; - pad->lower_alarm_limit = ppid->lolo; + if(paddr->pfield==(void *)&ppid->val){ + pad->upper_alarm_limit = ppid->hihi; + pad->upper_warning_limit = ppid->high; + pad->lower_warning_limit = ppid->low; + pad->lower_alarm_limit = ppid->lolo; + } else recGblGetAlarmDouble(paddr,pad); return(0); } - static void alarm(ppid) struct pidRecord *ppid; { - float ftemp; - float val=ppid->val; + double val; + float hyst, lalm, hihi, high, low, lolo; + unsigned short hhsv, llsv, hsv, lsv; - /* if difference is not > hysterisis use lalm not val */ - ftemp = ppid->lalm - ppid->val; - if(ftemp<0.0) ftemp = -ftemp; - if (ftemp < ppid->hyst) val=ppid->lalm; + if(ppid->udf == TRUE ){ + recGblSetSevr(ppid,UDF_ALARM,INVALID_ALARM); + return; + } + hihi = ppid->hihi; lolo = ppid->lolo; high = ppid->high; low = ppid->low; + hhsv = ppid->hhsv; llsv = ppid->llsv; hsv = ppid->hsv; lsv = ppid->lsv; + val = ppid->val; hyst = ppid->hyst; lalm = ppid->lalm; - /* alarm condition hihi */ - if (val > ppid->hihi && recGblSetSevr(ppid,HIHI_ALARM,ppid->hhsv)){ - ppid->lalm = val; - return; - } + /* alarm condition hihi */ + if (hhsv && (val >= hihi || ((lalm==hihi) && (val >= hihi-hyst)))){ + if (recGblSetSevr(ppid,HIHI_ALARM,ppid->hhsv)) ppid->lalm = hihi; + return; + } - /* alarm condition lolo */ - if (val < ppid->lolo && recGblSetSevr(ppid,LOLO_ALARM,ppid->llsv)){ - ppid->lalm = val; - return; - } + /* alarm condition lolo */ + if (llsv && (val <= lolo || ((lalm==lolo) && (val <= lolo+hyst)))){ + if (recGblSetSevr(ppid,LOLO_ALARM,ppid->llsv)) ppid->lalm = lolo; + return; + } - /* alarm condition high */ - if (val > ppid->high && recGblSetSevr(ppid,HIGH_ALARM,ppid->hsv)){ - ppid->lalm = val; - return; - } + /* alarm condition high */ + if (hsv && (val >= high || ((lalm==high) && (val >= high-hyst)))){ + if (recGblSetSevr(ppid,HIGH_ALARM,ppid->hsv)) ppid->lalm = high; + return; + } - /* alarm condition low */ - if (val < ppid->low && recGblSetSevr(ppid,LOW_ALARM,ppid->lsv)){ - ppid->lalm = val; - return; - } - return; + /* alarm condition low */ + if (lsv && (val <= low || ((lalm==low) && (val <= low+hyst)))){ + if (recGblSetSevr(ppid,LOW_ALARM,ppid->lsv)) ppid->lalm = low; + return; + } + + /* we get here only if val is out of alarm by at least hyst */ + ppid->lalm = val; + return; } static void monitor(ppid) @@ -379,13 +388,13 @@ struct pidRecord *ppid; /* fetch the controlled value */ if (ppid->cvl.type != DB_LINK) { /* nothing to control*/ - if (recGblSetSevr(ppid,SOFT_ALARM,VALID_ALARM)) return(0); + if (recGblSetSevr(ppid,SOFT_ALARM,INVALID_ALARM)) return(0); } options=0; nRequest=1; if(dbGetLink(&(ppid->cvl.value.db_link),(struct dbCommon *)ppid,DBR_FLOAT, &cval,&options,&nRequest)!=NULL) { - recGblSetSevr(ppid,LINK_ALARM,VALID_ALARM); + recGblSetSevr(ppid,LINK_ALARM,INVALID_ALARM); return(0); } /* fetch the setpoint */ @@ -394,19 +403,19 @@ struct pidRecord *ppid; nRequest=1; if(dbGetLink(&(ppid->stpl.value.db_link),(struct dbCommon *)ppid,DBR_FLOAT, &(ppid->val),&options,&nRequest)!=NULL) { - recGblSetSevr(ppid,LINK_ALARM,VALID_ALARM); + recGblSetSevr(ppid,LINK_ALARM,INVALID_ALARM); return(0); } else ppid->udf=FALSE; } if(ppid->stpl.type == CA_LINK && ppid->smsl == CLOSED_LOOP){ if(dbCaGetLink(&(ppid->stpl))!=NULL) { - recGblSetSevr(ppid,LINK_ALARM,VALID_ALARM); + recGblSetSevr(ppid,LINK_ALARM,INVALID_ALARM); return(0); } else ppid->udf=FALSE; } val = ppid->val; if (ppid->udf == TRUE ) { - recGblSetSevr(ppid,UDF_ALARM,VALID_ALARM); + recGblSetSevr(ppid,UDF_ALARM,INVALID_ALARM); return(0); } diff --git a/src/rec/recPulseCounter.c b/src/rec/recPulseCounter.c index 1d73379c2..ed669ec89 100644 --- a/src/rec/recPulseCounter.c +++ b/src/rec/recPulseCounter.c @@ -34,6 +34,8 @@ * .03 02-28-92 jba ANSI C changes * .04 04-10-92 jba pact now used to test for asyn processing, not status * .05 04-18-92 jba removed process from dev init_record parms + * .06 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .07 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro */ #include @@ -110,10 +112,7 @@ struct pcdset { /* pulseCounter input dset */ #define CTR_STOP 3 #define CTR_SETUP 4 -void monitor(); -/* Added for Channel Access Links */ -long dbCaAddInlink(); -long dbCaGetLink(); +static void monitor(); static long init_record(ppc,pass) @@ -127,7 +126,7 @@ static long init_record(ppc,pass) /* must have device support */ if(!(pdset = (struct pcdset *)(ppc->dset))) { - recGblRecordError(S_dev_noDSET,ppc,"pc: init_record"); + recGblRecordError(S_dev_noDSET,(void *)ppc,"pc: init_record"); return(S_dev_noDSET); } /* get the gate value if sgl is a constant*/ @@ -143,7 +142,7 @@ static long init_record(ppc,pass) /* must have cmd_pc functions defined */ if( (pdset->number < 5) || (pdset->cmd_pc == NULL) ) { - recGblRecordError(S_dev_missingSup,ppc,"pc: cmd_pc"); + recGblRecordError(S_dev_missingSup,(void *)ppc,"pc: cmd_pc"); return(S_dev_missingSup); } /* call device support init_record */ @@ -165,7 +164,7 @@ static long process(ppc) /* must have cmd_pc functions defined */ if( (pdset==NULL) || (pdset->cmd_pc==NULL) ) { ppc->pact=TRUE; - recGblRecordError(S_dev_missingSup,ppc,"cmd_pc"); + recGblRecordError(S_dev_missingSup,(void *)ppc,"cmd_pc"); return(S_dev_missingSup); } @@ -179,7 +178,7 @@ static long process(ppc) &ppc->sgv,&options,&nRequest); ppc->pact = FALSE; if(status!=0) { - recGblSetSevr(ppc,LINK_ALARM,VALID_ALARM); + recGblSetSevr(ppc,LINK_ALARM,INVALID_ALARM); } } if (ppc->sgl.type == CA_LINK){ @@ -187,10 +186,10 @@ static long process(ppc) status=dbCaGetLink(&(ppc->sgl)); ppc->pact = FALSE; if(status!=0) { - recGblSetSevr(ppc,LINK_ALARM,VALID_ALARM); + recGblSetSevr(ppc,LINK_ALARM,INVALID_ALARM); } } - if(status=0){ + if(status==0){ if(ppc->sgv != ppc->osgv){ /* soft gate changed */ save=ppc->cmd; if(ppc->sgv!=0){ @@ -202,7 +201,7 @@ static long process(ppc) ppc->cmd=save; ppc->osgv=ppc->sgv; if(status!=0) { - recGblSetSevr(ppc,SOFT_ALARM,VALID_ALARM); + recGblSetSevr(ppc,SOFT_ALARM,INVALID_ALARM); } } } @@ -226,7 +225,7 @@ static long process(ppc) monitor(ppc); /* process the forward scan link record */ - if (ppc->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)ppc->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(ppc); ppc->pact=FALSE; return(status); diff --git a/src/rec/recPulseDelay.c b/src/rec/recPulseDelay.c index 8c7050bb2..6e5aea6a8 100644 --- a/src/rec/recPulseDelay.c +++ b/src/rec/recPulseDelay.c @@ -36,6 +36,7 @@ * .05 04-10-92 jba pact now used to test for asyn processing, not status * .06 04-18-92 jba removed process from dev init_record parms * .07 06-02-92 jba changed graphic/control limits for dly,odly,wide,owid + * .08 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro */ #include @@ -101,7 +102,7 @@ struct pddset { /* pulseDelay input dset */ DEVSUPFUN get_ioint_info; DEVSUPFUN write_pd;/*(-1,0)=>(failure,success*/ }; -void monitor(); +static void monitor(); static long init_record(ppd,pass) struct pulseDelayRecord *ppd; @@ -114,13 +115,13 @@ static long init_record(ppd,pass) /* must have device support */ if(!(pdset = (struct pddset *)(ppd->dset))) { - recGblRecordError(S_dev_noDSET,ppd,"pd: init_record"); + recGblRecordError(S_dev_noDSET,(void *)ppd,"pd: init_record"); return(S_dev_noDSET); } /* must have write_pd functions defined */ if( (pdset->number < 5) || (pdset->write_pd == NULL) ) { - recGblRecordError(S_dev_missingSup,ppd,"pd: write_pd"); + recGblRecordError(S_dev_missingSup,(void *)ppd,"pd: write_pd"); return(S_dev_missingSup); } /* call device support init_record */ @@ -140,7 +141,7 @@ static long process(ppd) /* must have write_pd functions defined */ if( (pdset==NULL) || (pdset->write_pd==NULL) ) { ppd->pact=TRUE; - recGblRecordError(S_dev_missingSup,ppd,"write_pd"); + recGblRecordError(S_dev_missingSup,(void *)ppd,"write_pd"); return(S_dev_missingSup); } @@ -157,7 +158,7 @@ static long process(ppd) monitor(ppd); /* process the forward scan link record */ - if (ppd->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)ppd->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(ppd); ppd->pact=FALSE; return(status); diff --git a/src/rec/recPulseTrain.c b/src/rec/recPulseTrain.c index 1a1d18fac..640c96a0b 100644 --- a/src/rec/recPulseTrain.c +++ b/src/rec/recPulseTrain.c @@ -37,6 +37,8 @@ * .06 04-10-92 jba pact now used to test for asyn processing, not status * .07 04-18-92 jba removed process from dev init_record parms * .08 06-02-92 jba changed graphic/control limits for per,oper + * .09 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .10 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro */ #include @@ -113,10 +115,7 @@ struct ptdset { /* pulseTrain input dset */ #define CTR_STOP 3 #define CTR_SETUP 4 -void monitor(); -/* Added for Channel Access Links */ -long dbCaAddInlink(); -long dbCaGetLink(); +static void monitor(); static long init_record(ppt,pass) @@ -130,7 +129,7 @@ static long init_record(ppt,pass) /* must have device support */ if(!(pdset = (struct ptdset *)(ppt->dset))) { - recGblRecordError(S_dev_noDSET,ppt,"pt: init_record"); + recGblRecordError(S_dev_noDSET,(void *)ppt,"pt: init_record"); return(S_dev_noDSET); } /* get the gate value if sgl is a constant*/ @@ -146,7 +145,7 @@ static long init_record(ppt,pass) /* must have write_pt functions defined */ if( (pdset->number < 5) || (pdset->write_pt == NULL) ) { - recGblRecordError(S_dev_missingSup,ppt,"pt: write_pt"); + recGblRecordError(S_dev_missingSup,(void *)ppt,"pt: write_pt"); return(S_dev_missingSup); } /* call device support init_record */ @@ -169,7 +168,7 @@ static long process(ppt) /* must have write_pt functions defined */ if( (pdset==NULL) || (pdset->write_pt==NULL) ) { ppt->pact=TRUE; - recGblRecordError(S_dev_missingSup,ppt,"write_pt"); + recGblRecordError(S_dev_missingSup,(void *)ppt,"write_pt"); return(S_dev_missingSup); } @@ -183,7 +182,7 @@ static long process(ppt) &ppt->sgv,&options,&nRequest); ppt->pact = FALSE; if(status!=0) { - recGblSetSevr(ppt,LINK_ALARM,VALID_ALARM); + recGblSetSevr(ppt,LINK_ALARM,INVALID_ALARM); } } if (ppt->sgl.type == CA_LINK){ @@ -191,7 +190,7 @@ static long process(ppt) status=dbCaGetLink(&(ppt->sgl)); ppt->pact = FALSE; if(status!=0) { - recGblSetSevr(ppt,LINK_ALARM,VALID_ALARM); + recGblSetSevr(ppt,LINK_ALARM,INVALID_ALARM); } } if(status=0){ @@ -203,7 +202,7 @@ static long process(ppt) status=(*pdset->write_pt)(ppt); ppt->dcy=save; if(status!=0) { - recGblSetSevr(ppt,WRITE_ALARM,VALID_ALARM); + recGblSetSevr(ppt,WRITE_ALARM,INVALID_ALARM); } } ppt->osgv=ppt->sgv; @@ -227,7 +226,7 @@ static long process(ppt) monitor(ppt); /* process the forward scan link record */ - if (ppt->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)ppt->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(ppt); ppt->pact=FALSE; return(status); diff --git a/src/rec/recSel.c b/src/rec/recSel.c index 8e71fadeb..6c18cdace 100644 --- a/src/rec/recSel.c +++ b/src/rec/recSel.c @@ -38,7 +38,11 @@ * .05 02-28-92 jba Changed get_precision,get_graphic_double,get_control_double * .06 02-28-92 jba ANSI C changes * .07 06-02-92 jba changed graphic/control limits for hihi,high,low,lolo - * .07 06-18-92 jba changed graphic/control limits from loop to range test + * .08 06-18-92 jba changed graphic/control limits from loop to range test + * .09 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .10 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .11 07-21-92 jba changed alarm limits for non val related fields + * .12 08-06-92 jba New algorithm for calculating analog alarms */ #include @@ -100,14 +104,12 @@ struct rset selRSET={ #define SELECT_LOW 2 #define SELECT_MEDIAN 3 -void alarm(); -void monitor(); -int fetch_values(); -int do_sel(); -/* Added for Channel Access Links */ +static void alarm(); +static int do_sel(); +static int fetch_values(); +static void monitor(); + #define ARG_MAX 12 -long dbCaAddInlink(); -long dbCaGetLink(); /* Fldnames should have as many as ARG_MAX */ static char Fldnames[ARG_MAX][FLDNAME_SZ] = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"}; @@ -154,7 +156,7 @@ static long process(psel) psel->pact = TRUE; if(fetch_values(psel)==0) { if(do_sel(psel)!=0) { - recGblSetSevr(psel,CALC_ALARM,VALID_ALARM); + recGblSetSevr(psel,CALC_ALARM,INVALID_ALARM); } } @@ -167,8 +169,7 @@ static long process(psel) monitor(psel); /* process the forward scan link record */ - if (psel->flnk.type==DB_LINK) - dbScanPassive(((struct dbAddr *)psel->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(psel); psel->pact=FALSE; return(0); @@ -225,8 +226,6 @@ static long get_graphic_double(paddr,pgd) struct dbr_grDouble *pgd; { struct selRecord *psel=(struct selRecord *)paddr->precord; - double *pvalue,*plvalue; - int i; if(paddr->pfield==(void *)&psel->val || paddr->pfield==(void *)&psel->hihi @@ -257,8 +256,6 @@ static long get_control_double(paddr,pcd) struct dbr_ctrlDouble *pcd; { struct selRecord *psel=(struct selRecord *)paddr->precord; - double *pvalue; - int i; if(paddr->pfield==(void *)&psel->val || paddr->pfield==(void *)&psel->hihi @@ -284,59 +281,63 @@ static long get_control_double(paddr,pcd) return(0); } -static long get_alarm_double(paddr,pgd) +static long get_alarm_double(paddr,pad) struct dbAddr *paddr; - struct dbr_alDouble *pgd; + struct dbr_alDouble *pad; { struct selRecord *psel=(struct selRecord *)paddr->precord; - pgd->upper_alarm_limit = psel->hihi; - pgd->upper_warning_limit = psel->high; - pgd->lower_warning_limit = psel->low; - pgd->lower_alarm_limit = psel->lolo; + if(paddr->pfield==(void *)&psel->val ){ + pad->upper_alarm_limit = psel->hihi; + pad->upper_warning_limit = psel->high; + pad->lower_warning_limit = psel->low; + pad->lower_alarm_limit = psel->lolo; + } else recGblGetAlarmDouble(paddr,pad); return(0); } - static void alarm(psel) struct selRecord *psel; { - double ftemp; - double val=psel->val; + double val; + float hyst, lalm, hihi, high, low, lolo; + unsigned short hhsv, llsv, hsv, lsv; - /* undefined condition */ - if(psel->udf ==TRUE){ - if(recGblSetSevr(psel,UDF_ALARM,VALID_ALARM)) return; - } - /* if difference is not > hysterisis use lalm not val */ - ftemp = psel->lalm - psel->val; - if(ftemp<0.0) ftemp = -ftemp; - if (ftemp < psel->hyst) val=psel->lalm; + if(psel->udf == TRUE ){ + recGblSetSevr(psel,UDF_ALARM,INVALID_ALARM); + return; + } + hihi = psel->hihi; lolo = psel->lolo; high = psel->high; low = psel->low; + hhsv = psel->hhsv; llsv = psel->llsv; hsv = psel->hsv; lsv = psel->lsv; + val = psel->val; hyst = psel->hyst; lalm = psel->lalm; - /* alarm condition hihi */ - if (val > psel->hihi && recGblSetSevr(psel,HIHI_ALARM,psel->hhsv)){ - psel->lalm = val; - return; - } + /* alarm condition hihi */ + if (hhsv && (val >= hihi || ((lalm==hihi) && (val >= hihi-hyst)))){ + if (recGblSetSevr(psel,HIHI_ALARM,psel->hhsv)) psel->lalm = hihi; + return; + } - /* alarm condition lolo */ - if (val < psel->lolo && recGblSetSevr(psel,LOLO_ALARM,psel->llsv)){ - psel->lalm = val; - return; - } + /* alarm condition lolo */ + if (llsv && (val <= lolo || ((lalm==lolo) && (val <= lolo+hyst)))){ + if (recGblSetSevr(psel,LOLO_ALARM,psel->llsv)) psel->lalm = lolo; + return; + } - /* alarm condition high */ - if (val > psel->high && recGblSetSevr(psel,HIGH_ALARM,psel->hsv)){ - psel->lalm = val; - return; - } + /* alarm condition high */ + if (hsv && (val >= high || ((lalm==high) && (val >= high-hyst)))){ + if (recGblSetSevr(psel,HIGH_ALARM,psel->hsv)) psel->lalm = high; + return; + } - /* alarm condition low */ - if (val < psel->low && recGblSetSevr(psel,LOW_ALARM,psel->lsv)){ - psel->lalm = val; - return; - } - return; + /* alarm condition low */ + if (lsv && (val <= low || ((lalm==low) && (val <= low+hyst)))){ + if (recGblSetSevr(psel,LOW_ALARM,psel->lsv)) psel->lalm = low; + return; + } + + /* we get here only if val is out of alarm by at least hyst */ + psel->lalm = val; + return; } static void monitor(psel) @@ -474,13 +475,13 @@ struct selRecord *psel; nRequest=1; if(dbGetLink(&(psel->nvl.value.db_link),(struct dbCommon *)psel,DBR_USHORT, &(psel->seln),&options,&nRequest)!=NULL) { - recGblSetSevr(psel,LINK_ALARM,VALID_ALARM); + recGblSetSevr(psel,LINK_ALARM,INVALID_ALARM); return(-1); } } if(psel->nvl.type == CA_LINK ){ if(dbCaGetLink(&(psel->nvl)) !=NULL) { - recGblSetSevr(psel,LINK_ALARM,VALID_ALARM); + recGblSetSevr(psel,LINK_ALARM,INVALID_ALARM); return(-1); } } @@ -490,7 +491,7 @@ struct selRecord *psel; { if (dbCaGetLink(plink)) { - recGblSetSevr(psel,LINK_ALARM,VALID_ALARM); + recGblSetSevr(psel,LINK_ALARM,INVALID_ALARM); return(-1); } /* endif */ } /* endif */ @@ -499,7 +500,7 @@ struct selRecord *psel; status=dbGetLink(&plink->value.db_link,(struct dbCommon *)psel,DBR_DOUBLE, pvalue,&options,&nRequest); if(status!=0) { - recGblSetSevr(psel,LINK_ALARM,VALID_ALARM); + recGblSetSevr(psel,LINK_ALARM,INVALID_ALARM); return(-1); } } @@ -511,7 +512,7 @@ struct selRecord *psel; { if (dbCaGetLink(plink)) { - recGblSetSevr(psel,LINK_ALARM,VALID_ALARM); + recGblSetSevr(psel,LINK_ALARM,INVALID_ALARM); return(-1); } /* endif */ } /* endif */ @@ -520,7 +521,7 @@ struct selRecord *psel; status = dbGetLink(&plink->value.db_link,(struct dbCommon *)psel,DBR_DOUBLE, pvalue,&options,&nRequest); if(status!=0) { - recGblSetSevr(psel,LINK_ALARM,VALID_ALARM); + recGblSetSevr(psel,LINK_ALARM,INVALID_ALARM); return(-1); } } diff --git a/src/rec/recState.c b/src/rec/recState.c index 8bd17a47d..5c5399e58 100644 --- a/src/rec/recState.c +++ b/src/rec/recState.c @@ -34,6 +34,7 @@ * .02 11-11-91 jba Moved set and reset of alarm stat and sevr to macros * .03 02-05-92 jba Changed function arguments from paddr to precord * .04 02-28-92 jba ANSI C changes + * .05 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro */ #include @@ -89,7 +90,7 @@ struct rset stateRSET={ get_control_double, get_alarm_double }; -void monitor(); +static void monitor(); static long process(pstate) struct stateRecord *pstate; @@ -100,7 +101,7 @@ static long process(pstate) tsLocalTime(&pstate->time); monitor(pstate); /* process the forward scan link record */ - if (pstate->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)pstate->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(pstate); pstate->pact=FALSE; return(0); } diff --git a/src/rec/recSteppermotor.c b/src/rec/recSteppermotor.c index d4072f88d..b60ea31b6 100644 --- a/src/rec/recSteppermotor.c +++ b/src/rec/recSteppermotor.c @@ -68,7 +68,7 @@ * .25 08-28-91 lrd add open circuit detect on limit switches * .26 09-16-91 lrd fix IALG not 0 and SCAN not Passive - The motor * would continually attempt to initialize - * .27 12-09-91 lrd new INVALID severity for errors that invalidate + * .27 12-09-91 lrd new ININVALID severity for errors that invalidate * the results * .28 12-17-91 lrd changed the MDEL and ADEL deadbands so * the range for exceeding the deadband includes @@ -84,6 +84,9 @@ Make motor move whenever VAL field accessed * .27 04-08-92 mrk break out device support * .28 04-18-92 jba removed process from dev init_record parms + * .29 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .30 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .31 07-21-92 jba changed alarm limits for non val related fields */ #include @@ -158,18 +161,13 @@ struct smdset { #define POSITIVE_LIMIT 1 #define NEGATIVE_LIMIT 2 -void alarm(); -void monitor(); -void smcb_callback(); -void init_sm(); -void convert_sm(); -void positional_sm(); -void velocity_sm(); -void sm_get_position(); -/* Added for Channel Access Links */ -long dbCaAddInlink(); -long dbCaGetLink(); - +static void alarm(); +static void monitor(); +static void smcb_callback(); +static void init_sm(); +static void positional_sm(); +static void velocity_sm(); +static void sm_get_position(); static long init_record(psm,pass) @@ -182,12 +180,12 @@ static long init_record(psm,pass) if (pass==0) return(0); if(!(pdset = (struct smdset *)(psm->dset))) { - recGblRecordError(S_dev_noDSET,psm,"sm: init_record"); + recGblRecordError(S_dev_noDSET,(void *)psm,"sm: init_record"); return(S_dev_noDSET); } /* must have sm_command function defined */ if( (pdset->number < 5) || (pdset->sm_command == NULL) ) { - recGblRecordError(S_dev_missingSup,psm,"sm: init_record"); + recGblRecordError(S_dev_missingSup,(void *)psm,"sm: init_record"); return(S_dev_missingSup); } if( pdset->init_record ) { @@ -213,11 +211,10 @@ static long process(psm) struct steppermotorRecord *psm; { struct smdset *pdset = (struct smdset *)(psm->dset); - long status; if( (pdset==NULL) || (pdset->sm_command==NULL) ) { psm->pact=TRUE; - recGblRecordError(S_dev_missingSup,psm,"sm_command"); + recGblRecordError(S_dev_missingSup,(void *)psm,"sm_command"); return(S_dev_missingSup); } /* intialize the stepper motor record when the init bit is 0 */ @@ -241,7 +238,7 @@ static long process(psm) monitor(psm); /* process the forward scan link record */ - if (psm->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)psm->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(psm); psm->pact=FALSE; return(0); @@ -348,10 +345,16 @@ static long get_alarm_double(paddr,pad) { struct steppermotorRecord *psm=(struct steppermotorRecord *)paddr->precord; - pad->upper_alarm_limit = psm->hihi; - pad->upper_warning_limit = psm->high; - pad->lower_warning_limit = psm->low; - pad->lower_alarm_limit = psm->lolo; + if(paddr->pfield==(void *)&psm->val + || paddr->pfield==(void *)&psm->mpos + || paddr->pfield==(void *)&psm->rbv + || paddr->pfield==(void *)&psm->epos + || paddr->pfield==(void *)&psm->lval){ + pad->upper_alarm_limit = psm->hihi; + pad->upper_warning_limit = psm->high; + pad->lower_warning_limit = psm->low; + pad->lower_alarm_limit = psm->lolo; + } else recGblGetAlarmDouble(paddr,pad); return(0); } @@ -534,7 +537,7 @@ struct steppermotorRecord *psm; recGblResetSevr(psm,stat,sevr,nsta,nsev); post_events = FALSE; if (psm->mccw && psm->mcw){ /* limits disconnected */ - recGblSetSevr(psm,WRITE_ALARM,VALID_ALARM); + recGblSetSevr(psm,WRITE_ALARM,INVALID_ALARM); post_events = TRUE; }else if ((psm->ccw == 0) || (psm->cw == 0)){ /* limit violation */ recGblSetSevr(psm,HW_LIMIT_ALARM,psm->hlsv); @@ -592,7 +595,7 @@ struct steppermotorRecord *psm; /* move motor */ if ((*pdset->sm_command)(psm,SM_MOVE,psm->rval-psm->rrbv,0) < 0){ - recGblSetSevr(psm,WRITE_ALARM,VALID_ALARM); + recGblSetSevr(psm,WRITE_ALARM,INVALID_ALARM); } else { psm->rcnt++; if (psm->mlis.count){ @@ -647,7 +650,7 @@ struct steppermotorRecord *psm; /* initialize the motor */ /* set mode - first command checks card present */ if ((*pdset->sm_command)(psm,SM_MODE,psm->mode,0) < 0){ - recGblSetSevr(psm,WRITE_ALARM,VALID_ALARM); + recGblSetSevr(psm,WRITE_ALARM,INVALID_ALARM); psm->init = 1; return; } @@ -680,7 +683,7 @@ struct steppermotorRecord *psm; status = (*pdset->sm_command)(psm,SM_READ,0,0); } if (status < 0){ - recGblSetSevr(psm,WRITE_ALARM,VALID_ALARM); + recGblSetSevr(psm,WRITE_ALARM,INVALID_ALARM); return; } psm->init = -1; @@ -751,13 +754,13 @@ struct steppermotorRecord *psm; if(dbGetLink(&(psm->dol.value.db_link),(struct dbCommon *)psm,DBR_FLOAT, &(psm->val),&options,&nRequest)){ - recGblSetSevr(psm,LINK_ALARM,VALID_ALARM); + recGblSetSevr(psm,LINK_ALARM,INVALID_ALARM); return; } else psm->udf = FALSE; } if (psm->dol.type == CA_LINK){ if(dbCaGetLink(&(psm->dol))){ - recGblSetSevr(psm,LINK_ALARM,VALID_ALARM); + recGblSetSevr(psm,LINK_ALARM,INVALID_ALARM); return; } else psm->udf = FALSE; } @@ -793,7 +796,7 @@ struct steppermotorRecord *psm; } /* move motor */ if ((*pdset->sm_command)(psm,SM_MOVE,psm->rval-psm->rrbv,0) < 0){ - recGblSetSevr(psm,WRITE_ALARM,VALID_ALARM); + recGblSetSevr(psm,WRITE_ALARM,INVALID_ALARM); } } @@ -820,13 +823,13 @@ struct steppermotorRecord *psm; if(dbGetLink(&(psm->dol.value.db_link),(struct dbCommon *)psm,DBR_FLOAT, &(psm->val),&options,&nRequest)) { - recGblSetSevr(psm,LINK_ALARM,VALID_ALARM); + recGblSetSevr(psm,LINK_ALARM,INVALID_ALARM); return; } else psm->udf=FALSE; } if (psm->dol.type == CA_LINK){ if(dbCaGetLink(&(psm->dol))){ - recGblSetSevr(psm,LINK_ALARM,VALID_ALARM); + recGblSetSevr(psm,LINK_ALARM,INVALID_ALARM); return; } else psm->udf=FALSE; } @@ -861,7 +864,7 @@ struct steppermotorRecord *psm; /*the last arg of next call is check for direction */ if((*pdset->sm_command)(psm,SM_MOTION,1,(psm->val < 0))){ - recGblSetSevr(psm,WRITE_ALARM,VALID_ALARM); + recGblSetSevr(psm,WRITE_ALARM,INVALID_ALARM); return; } psm->cvel = 0; @@ -910,7 +913,7 @@ struct steppermotorRecord *psm; if (reset == 0) psm->init = 1; if(dbGetLink(&(psm->rdbl.value.db_link),(struct dbCommon *)psm,DBR_FLOAT, &new_pos,&options,&nRequest)){ - recGblSetSevr(psm,READ_ALARM,VALID_ALARM); + recGblSetSevr(psm,READ_ALARM,INVALID_ALARM); psm->init = reset; return; } diff --git a/src/rec/recStringin.c b/src/rec/recStringin.c index d62c46ac2..9ad41cd59 100644 --- a/src/rec/recStringin.c +++ b/src/rec/recStringin.c @@ -34,6 +34,8 @@ * .03 02-28-92 jba ANSI C changes * .04 04-10-92 jba pact now used to test for asyn processing, not status * .05 04-18-92 jba removed process from dev init_record parms + * .06 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .07 08-13-92 jba Added simulation processing */ @@ -99,7 +101,9 @@ struct stringindset { /* stringin input dset */ DEVSUPFUN get_ioint_info; DEVSUPFUN read_stringin; /*returns: (-1,0)=>(failure,success)*/ }; -void monitor(); +static void monitor(); +static long readValue(); + static long init_record(pstringin,pass) struct stringinRecord *pstringin; @@ -110,13 +114,49 @@ static long init_record(pstringin,pass) if (pass==0) return(0); + /* stringin.siml must be a CONSTANT or a PV_LINK or a DB_LINK */ + switch (pstringin->siml.type) { + case (CONSTANT) : + pstringin->simm = pstringin->siml.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(pstringin->siml), (void *) pstringin, "SIMM"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)pstringin, + "stringin: init_record Illegal SIML field"); + return(S_db_badField); + } + + /* stringin.siol must be a CONSTANT or a PV_LINK or a DB_LINK */ + switch (pstringin->siol.type) { + case (CONSTANT) : + if (pstringin->siol.value.value!=0.0 ){ + sprintf(pstringin->sval,"%-14.7g",pstringin->siol.value.value); + } + break; + case (PV_LINK) : + status = dbCaAddInlink(&(pstringin->siol), (void *) pstringin, "SVAL"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)pstringin, + "stringin: init_record Illegal SIOL field"); + return(S_db_badField); + } + if(!(pdset = (struct stringindset *)(pstringin->dset))) { - recGblRecordError(S_dev_noDSET,pstringin,"stringin: init_record"); + recGblRecordError(S_dev_noDSET,(void *)pstringin,"stringin: init_record"); return(S_dev_noDSET); } /* must have read_stringin function defined */ if( (pdset->number < 5) || (pdset->read_stringin == NULL) ) { - recGblRecordError(S_dev_missingSup,pstringin,"stringin: init_record"); + recGblRecordError(S_dev_missingSup,(void *)pstringin,"stringin: init_record"); return(S_dev_missingSup); } if( pdset->init_record ) { @@ -134,11 +174,11 @@ static long process(pstringin) if( (pdset==NULL) || (pdset->read_stringin==NULL) ) { pstringin->pact=TRUE; - recGblRecordError(S_dev_missingSup,pstringin,"read_stringin"); + recGblRecordError(S_dev_missingSup,(void *)pstringin,"read_stringin"); return(S_dev_missingSup); } - status=(*pdset->read_stringin)(pstringin); /* read the new value */ + status=readValue(pstringin); /* read the new value */ /* check if device support set pact */ if ( !pact && pstringin->pact ) return(0); pstringin->pact = TRUE; @@ -147,10 +187,8 @@ static long process(pstringin) /* check event list */ monitor(pstringin); - /* process the forward scan link record */ - if (pstringin->flnk.type==DB_LINK) - dbScanPassive(((struct dbAddr *)pstringin->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(pstringin); pstringin->pact=FALSE; return(status); @@ -195,3 +233,42 @@ static void monitor(pstringin) } return; } + +static long readValue(pstringin) + struct stringinRecord *pstringin; +{ + long status; + struct stringindset *pdset = (struct stringindset *) (pstringin->dset); + long nRequest=1; + + + if (pstringin->pact == TRUE){ + status=(*pdset->read_stringin)(pstringin); + return(status); + } + + status=recGblGetLinkValue(&(pstringin->siml), + (void *)pstringin,DBR_ENUM,&(pstringin->simm),&nRequest); + if (status) + return(status); + + if (pstringin->simm == NO){ + status=(*pdset->read_stringin)(pstringin); + return(status); + } + if (pstringin->simm == YES){ + status=recGblGetLinkValue(&(pstringin->siol), + (void *)pstringin,DBR_STRING,pstringin->sval,&nRequest); + if (status==0){ + strcpy(pstringin->val,pstringin->sval); + pstringin->udf=FALSE; + } + } else { + status=-1; + recGblSetSevr(pstringin,SOFT_ALARM,INVALID_ALARM); + return(status); + } + recGblSetSevr(pstringin,SIMM_ALARM,pstringin->sims); + + return(status); +} diff --git a/src/rec/recStringout.c b/src/rec/recStringout.c index dcfdcc6ef..b7b093e31 100644 --- a/src/rec/recStringout.c +++ b/src/rec/recStringout.c @@ -35,6 +35,10 @@ * .04 02-28-92 jba ANSI C changes * .05 04-10-92 jba pact now used to test for asyn processing, not status * .06 04-18-92 jba removed process from dev init_record parms + * .07 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .08 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .09 08-14-92 jba Added simulation processing + * .10 08-19-92 jba Added code for invalid alarm output action */ @@ -100,10 +104,8 @@ struct stringoutdset { /* stringout input dset */ DEVSUPFUN get_ioint_info; DEVSUPFUN write_stringout;/*(-1,0)=>(failure,success)*/ }; -void monitor(); -/* Added for Channel Access Links */ -long dbCaAddInlink(); -long dbCaGetLink(); +static void monitor(); +static long writeValue(); static long init_record(pstringout,pass) @@ -115,13 +117,36 @@ static long init_record(pstringout,pass) if (pass==0) return(0); + /* stringout.siml must be a CONSTANT or a PV_LINK or a DB_LINK */ + switch (pstringout->siml.type) { + case (CONSTANT) : + pstringout->simm = pstringout->siml.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(pstringout->siml), (void *) pstringout, "SIMM"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)pstringout, + "stringout: init_record Illegal SIML field"); + return(S_db_badField); + } + + /* stringout.siol may be a PV_LINK */ + if (pstringout->siol.type == PV_LINK){ + status = dbCaAddOutlink(&(pstringout->siol), (void *) pstringout, "VAL"); + if(status) return(status); + } + if(!(pdset = (struct stringoutdset *)(pstringout->dset))) { - recGblRecordError(S_dev_noDSET,pstringout,"stringout: init_record"); + recGblRecordError(S_dev_noDSET,(void *)pstringout,"stringout: init_record"); return(S_dev_noDSET); } /* must have write_stringout functions defined */ if( (pdset->number < 5) || (pdset->write_stringout == NULL) ) { - recGblRecordError(S_dev_missingSup,pstringout,"stringout: init_record"); + recGblRecordError(S_dev_missingSup,(void *)pstringout,"stringout: init_record"); return(S_dev_missingSup); } /* get the initial value dol is a constant*/ @@ -152,7 +177,7 @@ static long process(pstringout) if( (pdset==NULL) || (pdset->write_stringout==NULL) ) { pstringout->pact=TRUE; - recGblRecordError(S_dev_missingSup,pstringout,"write_stringout"); + recGblRecordError(S_dev_missingSup,(void *)pstringout,"write_stringout"); return(S_dev_missingSup); } if (!pstringout->pact) { @@ -166,7 +191,7 @@ static long process(pstringout) DBR_STRING,pstringout->val,&options,&nRequest); pstringout->pact = FALSE; if(!status==0){ - recGblSetSevr(pstringout,LINK_ALARM,VALID_ALARM); + recGblSetSevr(pstringout,LINK_ALARM,INVALID_ALARM); } else pstringout->udf=FALSE; } if((pstringout->dol.type == CA_LINK) && (pstringout->omsl == CLOSED_LOOP)){ @@ -174,14 +199,38 @@ static long process(pstringout) status = dbCaGetLink(&(pstringout->dol)); pstringout->pact = FALSE; if(!status==0){ - recGblSetSevr(pstringout,LINK_ALARM,VALID_ALARM); + recGblSetSevr(pstringout,LINK_ALARM,INVALID_ALARM); } else pstringout->udf=FALSE; } /* endif */ } - if(status==0) { - status=(*pdset->write_stringout)(pstringout); /* write the new value */ - } + if(pstringout->udf == TRUE ){ + recGblSetSevr(pstringout,UDF_ALARM,INVALID_ALARM); + return(-1); + } + + if (pstringout->nsev < INVALID_ALARM ) + status=writeValue(pstringout); /* write the new value */ + else { + switch (pstringout->ivoa) { + case (IVOA_CONTINUE) : + status=writeValue(pstringout); /* write the new value */ + break; + case (IVOA_NO_OUTPUT) : + break; + case (IVOA_OUTPUT_IVOV) : + if(pstringout->pact == FALSE){ + strcpy(pstringout->val,pstringout->ivov); + } + status=writeValue(pstringout); /* write the new value */ + break; + default : + status=-1; + recGblRecordError(S_db_badField,(void *)pstringout, + "ao:process Illegal IVOA field"); + } + } + /* check if device support set pact */ if ( !pact && pstringout->pact ) return(0); pstringout->pact = TRUE; @@ -192,8 +241,7 @@ static long process(pstringout) monitor(pstringout); /* process the forward scan link record */ - if (pstringout->flnk.type==DB_LINK) - dbScanPassive(((struct dbAddr *)pstringout->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(pstringout); pstringout->pact=FALSE; return(status); @@ -237,3 +285,37 @@ static void monitor(pstringout) } return; } + +static long writeValue(pstringout) + struct stringoutRecord *pstringout; +{ + long status; + struct stringoutdset *pdset = (struct stringoutdset *) (pstringout->dset); + long nRequest=1; + + if (pstringout->pact == TRUE){ + status=(*pdset->write_stringout)(pstringout); + return(status); + } + + status=recGblGetLinkValue(&(pstringout->siml), + (void *)pstringout,DBR_ENUM,&(pstringout->simm),&nRequest); + if (status) + return(status); + + if (pstringout->simm == NO){ + status=(*pdset->write_stringout)(pstringout); + return(status); + } + if (pstringout->simm == YES){ + status=recGblPutLinkValue(&(pstringout->siol), + (void *)pstringout,DBR_STRING,pstringout->val,&nRequest); + } else { + status=-1; + recGblSetSevr(pstringout,SOFT_ALARM,INVALID_ALARM); + return(status); + } + recGblSetSevr(pstringout,SIMM_ALARM,pstringout->sims); + + return(status); +} diff --git a/src/rec/recSub.c b/src/rec/recSub.c index 9ceb955c8..543ade054 100644 --- a/src/rec/recSub.c +++ b/src/rec/recSub.c @@ -38,6 +38,11 @@ * .06 02-28-92 jba ANSI C changes * .07 04-10-92 jba pact now used to test for asyn processing, not status * .08 06-02-92 jba changed graphic/control limits for hihi,high,low,lolo + * .09 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .10 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .11 07-21-92 jba changed alarm limits for non val related fields + * .12 08-06-92 jba New algorithm for calculating analog alarms + * .13 08-06-92 jba monitor now posts events for changes in a-l */ #include @@ -96,16 +101,12 @@ struct rset subRSET={ get_control_double, get_alarm_double }; +static void alarm(); +static long do_sub(); +static long fetch_values(); +static void monitor(); + #define ARG_MAX 12 -void alarm(); -void monitor(); -long do_sub(); -long fetch_values(); -/* Added for Channel Access Links */ -long dbCaAddInlink(); -long dbCaGetLink(); -#define ARG_MAX 12 - /* Fldnames should have as many as ARG_MAX */ static char Fldnames[ARG_MAX][FLDNAME_SZ] = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"}; @@ -145,7 +146,7 @@ static long init_record(psub,pass) strcat(temp,psub->inam); ret = symFindByName(sysSymTbl,temp,(void *)&psub->sadr,(void *)&sub_type); if ((ret !=OK) || ((sub_type & N_TEXT) == 0)){ - recGblRecordError(S_db_BadSub,psub,"recSub(init_record)"); + recGblRecordError(S_db_BadSub,(void *)psub,"recSub(init_record)"); return(S_db_BadSub); } @@ -162,7 +163,7 @@ static long init_record(psub,pass) strcat(temp,psub->snam); ret = symFindByName(sysSymTbl,temp,(void *)&psub->sadr,(void *)&sub_type); if ((ret < 0) || ((sub_type & N_TEXT) == 0)){ - recGblRecordError(S_db_BadSub,psub,"recSub(init_record)"); + recGblRecordError(S_db_BadSub,(void *)psub,"recSub(init_record)"); return(S_db_BadSub); } psub->styp = sub_type; @@ -188,7 +189,7 @@ static long process(psub) /* check event list */ monitor(psub); /* process the forward scan link record */ - if (psub->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)psub->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(psub); psub->pact = FALSE; return(0); } @@ -290,53 +291,57 @@ static long get_alarm_double(paddr,pad) { struct subRecord *psub=(struct subRecord *)paddr->precord; - pad->upper_alarm_limit = psub->hihi; - pad->upper_warning_limit = psub->high; - pad->lower_warning_limit = psub->low; - pad->lower_alarm_limit = psub->lolo; + if(paddr->pfield==(void *)&psub->val){ + pad->upper_alarm_limit = psub->hihi; + pad->upper_warning_limit = psub->high; + pad->lower_warning_limit = psub->low; + pad->lower_alarm_limit = psub->lolo; + } else recGblGetAlarmDouble(paddr,pad); return(0); } - static void alarm(psub) struct subRecord *psub; { - double ftemp; - double val=psub->val; + double val; + float hyst, lalm, hihi, high, low, lolo; + unsigned short hhsv, llsv, hsv, lsv; - /* undefined condition */ - if(psub->udf == TRUE) { - if(recGblSetSevr(psub,UDF_ALARM,VALID_ALARM)) return; - } - /* if difference is not > hysterisis use lalm not val */ - ftemp = psub->lalm - psub->val; - if(ftemp<0.0) ftemp = -ftemp; - if (ftemp < psub->hyst) val=psub->lalm; + if(psub->udf == TRUE ){ + recGblSetSevr(psub,UDF_ALARM,INVALID_ALARM); + return; + } + hihi = psub->hihi; lolo = psub->lolo; high = psub->high; low = psub->low; + hhsv = psub->hhsv; llsv = psub->llsv; hsv = psub->hsv; lsv = psub->lsv; + val = psub->val; hyst = psub->hyst; lalm = psub->lalm; - /* alarm condition hihi */ - if (val > psub->hihi && recGblSetSevr(psub,HIHI_ALARM,psub->hhsv)){ - psub->lalm = val; - return; - } + /* alarm condition hihi */ + if (hhsv && (val >= hihi || ((lalm==hihi) && (val >= hihi-hyst)))){ + if (recGblSetSevr(psub,HIHI_ALARM,psub->hhsv)) psub->lalm = hihi; + return; + } - /* alarm condition lolo */ - if (val < psub->lolo && recGblSetSevr(psub,LOLO_ALARM,psub->llsv)){ - psub->lalm = val; - return; - } + /* alarm condition lolo */ + if (llsv && (val <= lolo || ((lalm==lolo) && (val <= lolo+hyst)))){ + if (recGblSetSevr(psub,LOLO_ALARM,psub->llsv)) psub->lalm = lolo; + return; + } - /* alarm condition high */ - if (val > psub->high && recGblSetSevr(psub,HIGH_ALARM,psub->hsv)){ - psub->lalm = val; - return; - } + /* alarm condition high */ + if (hsv && (val >= high || ((lalm==high) && (val >= high-hyst)))){ + if (recGblSetSevr(psub,HIGH_ALARM,psub->hsv)) psub->lalm = high; + return; + } - /* alarm condition low */ - if (val < psub->low && recGblSetSevr(psub,LOW_ALARM,psub->lsv)){ - psub->lalm = val; - return; - } - return; + /* alarm condition low */ + if (lsv && (val <= low || ((lalm==low) && (val <= low+hyst)))){ + if (recGblSetSevr(psub,LOW_ALARM,psub->lsv)) psub->lalm = low; + return; + } + + /* we get here only if val is out of alarm by at least hyst */ + psub->lalm = val; + return; } static void monitor(psub) @@ -383,14 +388,14 @@ static void monitor(psub) /* send out monitors connected to the value field */ if (monitor_mask){ db_post_events(psub,&psub->val,monitor_mask); - /* check all input fields for changes*/ - for(i=0, pnew=&psub->a, pprev=&psub->la; ia, pprev=&psub->la; ivalue.db_link,(struct dbCommon *)psub,DBR_DOUBLE, pvalue,&options,&nRequest); if(status!=0) { - recGblSetSevr(psub,LINK_ALARM,VALID_ALARM); + recGblSetSevr(psub,LINK_ALARM,INVALID_ALARM); return(-1); } } /* endif */ @@ -440,7 +445,7 @@ struct subRecord *psub; /* pointer to subroutine record */ /* call the subroutine */ psubroutine = (FUNCPTR)(psub->sadr); if(psubroutine==NULL) { - recGblSetSevr(psub,BAD_SUB_ALARM,VALID_ALARM); + recGblSetSevr(psub,BAD_SUB_ALARM,INVALID_ALARM); return(0); } status = psubroutine(psub); diff --git a/src/rec/recTimer.c b/src/rec/recTimer.c index 0bb55aef4..151aca2ea 100644 --- a/src/rec/recTimer.c +++ b/src/rec/recTimer.c @@ -46,6 +46,8 @@ * .13 12-12-91 jba Set cmd to zero in io-interrupt processing * .14 02-05-92 jba Changed function arguments from paddr to precord * .15 02-28-92 jba ANSI C changes + * .16 07-15-92 jba changed VALID_ALARM to INVALID alarm + * .17 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro */ #include @@ -102,10 +104,6 @@ struct rset timerRSET={ get_control_double, get_alarm_double }; -/* Added for Channel Access Links */ -long dbCaAddInlink(); -long dbCaGetLink(); - /* because the driver does all the work just declare device support here*/ static long get_ioint_info(); struct dset devTmMizar8310={4,NULL,NULL,NULL,get_ioint_info}; @@ -178,7 +176,7 @@ static long process(ptimer) /* check event list */ monitor(ptimer); /* process the forward scan link record */ - if (ptimer->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)ptimer->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(ptimer); ptimer->pact=FALSE; return(0); @@ -299,7 +297,7 @@ struct timerRecord *ptimer; status = dbGetLink(&(ptimer->torg.value.db_link),(struct dbCommon *)ptimer,DBR_FLOAT, &(ptimer->trdl),&options,&nRequest); if(status!=0){ - recGblSetSevr(ptimer,LINK_ALARM,VALID_ALARM); + recGblSetSevr(ptimer,LINK_ALARM,INVALID_ALARM); return; } } @@ -308,12 +306,12 @@ struct timerRecord *ptimer; status = dbCaGetLink(&(ptimer->torg)); if(status!=0) { - recGblSetSevr(ptimer,LINK_ALARM,VALID_ALARM); + recGblSetSevr(ptimer,LINK_ALARM,INVALID_ALARM); return; } /* endif */ } /* endif */ if (ptimer->out.type != VME_IO) { - recGblSetSevr(ptimer,WRITE_ALARM,VALID_ALARM); + recGblSetSevr(ptimer,WRITE_ALARM,INVALID_ALARM); return; } pvmeio = (struct vmeio *)(&ptimer->out.value); @@ -340,7 +338,7 @@ struct timerRecord *ptimer; ((ptimer->tevt == 0)?0:post_event), /* addr of event post routine */ (int)ptimer->tevt) /* event to post on trigger */ != 0){ - recGblSetSevr(ptimer,WRITE_ALARM,VALID_ALARM); + recGblSetSevr(ptimer,WRITE_ALARM,INVALID_ALARM); } return; } @@ -362,7 +360,7 @@ struct timerRecord *ptimer; /* initiate the write */ if (ptimer->out.type != VME_IO) { - recGblRecordError(S_dev_badOutType,ptimer,"read_timer"); + recGblRecordError(S_dev_badOutType,(void *)ptimer,"read_timer"); return; } diff --git a/src/rec/recWaveform.c b/src/rec/recWaveform.c index 58003a2f3..c61332dc8 100644 --- a/src/rec/recWaveform.c +++ b/src/rec/recWaveform.c @@ -55,6 +55,8 @@ * .15 02-28-92 jba ANSI C changes * .16 04-10-92 jba pact now used to test for asyn processing, not status * .17 04-18-92 jba removed process from dev init_record parms + * .18 07-16-92 jba added invalid alarm fwd link test and chngd fwd lnk to macro + * .19 08-14-92 jba Added simulation processing */ #include @@ -124,8 +126,9 @@ struct wfdset { /* waveform dset */ /*sizes of field types*/ static int sizeofTypes[] = {0,1,1,2,2,4,4,4,8,2}; -void monitor(); +static void monitor(); +static long readValue(); /*Following from timing system */ extern unsigned int gts_trigger_counter; @@ -149,14 +152,49 @@ static long init_record(pwf,pass) pwf->nord = 0; return(0); } + + /* wf.siml must be a CONSTANT or a PV_LINK or a DB_LINK */ + switch (pwf->siml.type) { + case (CONSTANT) : + pwf->simm = pwf->siml.value.value; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(pwf->siml), (void *) pwf, "SIMM"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)pwf, + "wf: init_record Illegal SIML field"); + return(S_db_badField); + } + + /* wf.siol must be a CONSTANT or a PV_LINK or a DB_LINK */ + switch (pwf->siol.type) { + case (CONSTANT) : + pwf->nord = 0; + break; + case (PV_LINK) : + status = dbCaAddInlink(&(pwf->siol), (void *) pwf, "VAL"); + if(status) return(status); + break; + case (DB_LINK) : + break; + default : + recGblRecordError(S_db_badField,(void *)pwf, + "wf: init_record Illegal SIOL field"); + return(S_db_badField); + } + /* must have dset defined */ if(!(pdset = (struct wfdset *)(pwf->dset))) { - recGblRecordError(S_dev_noDSET,pwf,"wf: init_record"); + recGblRecordError(S_dev_noDSET,(void *)pwf,"wf: init_record"); return(S_dev_noDSET); } /* must have read_wf function defined */ if( (pdset->number < 5) || (pdset->read_wf == NULL) ) { - recGblRecordError(S_dev_missingSup,pwf,"wf: init_record"); + recGblRecordError(S_dev_missingSup,(void *)pwf,"wf: init_record"); return(S_dev_missingSup); } if( pdset->init_record ) { @@ -174,14 +212,14 @@ static long process(pwf) if( (pdset==NULL) || (pdset->read_wf==NULL) ) { pwf->pact=TRUE; - recGblRecordError(S_dev_missingSup,pwf,"read_wf"); + recGblRecordError(S_dev_missingSup,(void *)pwf,"read_wf"); return(S_dev_missingSup); } /* event throttling */ if (pwf->scan == SCAN_IO_EVENT){ if ((pwf->evnt != 0) && (gts_trigger_counter != 0)){ if ((gts_trigger_counter % pwf->evnt) != 0){ - status=(*pdset->read_wf)(pwf); + status=readValue(pwf); return(0); } } @@ -189,7 +227,7 @@ static long process(pwf) if ( pact && pwf->busy ) return(0); - status=(*pdset->read_wf)(pwf); /* read the new value */ + status=readValue(pwf); /* read the new value */ /* check if device support set pact */ if ( !pact && pwf->pact ) return(0); pwf->pact = TRUE; @@ -199,7 +237,7 @@ static long process(pwf) monitor(pwf); /* process the forward scan link record */ - if (pwf->flnk.type==DB_LINK) dbScanPassive(((struct dbAddr *)pwf->flnk.value.db_link.pdbAddr)->precord); + recGblFwdLink(pwf); pwf->pact=FALSE; return(0); @@ -325,3 +363,44 @@ static void monitor(pwf) return; } + +static long readValue(pwf) + struct waveformRecord *pwf; +{ + long status; + struct wfdset *pdset = (struct wfdset *) (pwf->dset); + long nRequest=1; + + + if (pwf->pact == TRUE){ + status=(*pdset->read_wf)(pwf); + return(status); + } + + status=recGblGetLinkValue(&(pwf->siml), + (void *)pwf,DBR_ENUM,&(pwf->simm),&nRequest); + if (status) + return(status); + + if (pwf->simm == NO){ + status=(*pdset->read_wf)(pwf); + return(status); + } + if (pwf->simm == YES){ + nRequest=pwf->nelm; + status=recGblGetLinkValue(&(pwf->siol), + (void *)pwf,pwf->ftvl,&(pwf->bptr),&nRequest); + pwf->nord = nRequest; + if (status==0){ + pwf->udf=FALSE; + } + } else { + status=-1; + recGblSetSevr(pwf,SOFT_ALARM,INVALID_ALARM); + return(status); + } + recGblSetSevr(pwf,SIMM_ALARM,pwf->sims); + + return(status); +} +