From 2b6886385ba0546be3c3eade8079effbf2986489 Mon Sep 17 00:00:00 2001 From: Marty Kraimer Date: Fri, 30 Nov 1990 09:51:58 +0000 Subject: [PATCH] makerelease --- src/rec/recAi.c | 223 +++++-------- src/rec/recAo.c | 381 ++++++++++----------- src/rec/recBi.c | 123 +++---- src/rec/recBo.c | 204 ++++++------ src/rec/recCalc.c | 715 ++++++++++++++++++---------------------- src/rec/recCompress.c | 480 ++++++++++++++------------- src/rec/recFanout.c | 30 +- src/rec/recMbbi.c | 294 +++++++++-------- src/rec/recMbbo.c | 317 ++++++++++-------- src/rec/recPermissive.c | 22 +- src/rec/recPid.c | 454 ++++++++++++------------- src/rec/recSel.c | 331 ++++++++----------- src/rec/recState.c | 26 +- src/rec/recSub.c | 691 +++++++++----------------------------- src/rec/recTimer.c | 188 +++++------ src/rec/recWaveform.c | 384 +++++++-------------- 16 files changed, 2107 insertions(+), 2756 deletions(-) diff --git a/src/rec/recAi.c b/src/rec/recAi.c index 18e1fa434..6f7a7a67d 100644 --- a/src/rec/recAi.c +++ b/src/rec/recAi.c @@ -112,11 +112,15 @@ struct aidset { /* analog input dset */ DEVSUPFUN init; DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ai;/*(-1,0,1)=>(failure,success,don't Continue*/ + DEVSUPFUN read_ai;/*(0,1,2)=> success and */ + /*(convert,don't continue, don't convert)*/ + /* if convert then raw value stored in rval */ DEVSUPFUN special_linconv; }; -long convert_ai(); +void convert(); +void alarm(); +void monitor(); static long report(fp,paddr) FILE *fp; @@ -144,8 +148,7 @@ static long report(fp,paddr) if(recGblReportGblChoice(fp,pai,"LLSV",pai->llsv)) return(-1); if(fprintf(fp,"HYST %-12.4G ADEL %-12.4G MDEL %-12.4G ESLO %-12.4G\n", pai->hyst,pai->adel,pai->mdel,pai->eslo)) return(-1); - if(fprintf(fp,"RVAL 0x%-8X ACHN %d\n", - pai->rval,pai->achn)) return(-1); + if(fprintf(fp,"RVAL 0x%-8X\n",pai->rval)) return(-1); if(fprintf(fp,"LALM %-12.4G ALST %-12.4G MLST %-12.4G\n", pai->lalm,pai->alst,pai->mlst)) return(-1); if(fprintf(fp,"LBRK %d\n",pai->lbrk)) return(-1); @@ -158,18 +161,23 @@ static long init_record(pai) struct aidset *pdset; long status; + /* initialize so that first alarm, archive, and monitor get generated*/ + pai->lalm = 1e30; + pai->alst = 1e30; + pai->mlst = 1e30; + if(!(pdset = (struct aidset *)(pai->dset))) { recGblRecordError(S_dev_noDSET,pai,"ai: init_record"); return(S_dev_noDSET); } /* must have read_ai function defined */ - if( (pdset->number < 5) || (pdset->read_ai == NULL) ) { + if( (pdset->number < 6) || (pdset->read_ai == NULL) ) { recGblRecordError(S_dev_missingSup,pai,"ai: init_record"); return(S_dev_missingSup); } pai->init = TRUE; if( pdset->init_record ) { - if((status=(*pdset->init_record)(pai))) return(status); + if((status=(*pdset->init_record)(pai,process))) return(status); } if(pai->linr >= 2) { /*must find breakpoint table*/ if( !cvtTable || (cvtTable->number < pai->linr) @@ -196,43 +204,19 @@ static long process(paddr) return(S_dev_missingSup); } + /*pact must not be set true until read_ai completes*/ status=(*pdset->read_ai)(pai); /* read the new value */ pai->pact = TRUE; - /* status is one if an asynchronous record is being processed*/ - if(status==1) return(1); - else if(status == -1) { - if(pai->stat != READ_ALARM) {/* error. set alarm condition */ - pai->stat = READ_ALARM; - pai->sevr = MAJOR_ALARM; - pai->achn=1; - } - } - else if(status == -2) { - if(pai->stat != HW_LIMIT_ALARM) {/* error. set alarm condition */ - pai->stat = HW_LIMIT_ALARM; - pai->sevr = MAJOR_ALARM; - pai->achn=1; - } - status=0; - } - else if(status!=0) return(status); - else if(pai->stat == READ_ALARM || pai->stat == HW_LIMIT_ALARM) { - pai->stat = NO_ALARM; - pai->sevr = NO_ALARM; - pai->achn=1; - } - if(status==0) status=convert_ai(pai); + if(status==1) return(0); + if(status==2) status=0; else convert(pai); /* check for alarms */ alarm(pai); - - /* check event list */ - if(!pai->disa) status = monitor(pai); - + monitor(pai); /* process the forward scan link record */ - if (pai->flnk.type==DB_LINK) dbScanPassive(&pai->flnk.value); + if (pai->flnk.type==DB_LINK) dbScanPassive(&pai->flnk.value.db_link.pdbAddr); pai->init=FALSE; pai->pact=FALSE; @@ -249,7 +233,7 @@ static long special(paddr,after) switch(special_type) { case(SPC_LINCONV): - if(pdset->number<5 || !(pdset->special_linconv)) { + if(pdset->number<6 || !(pdset->special_linconv)) { recGblDbaddrError(S_db_noMod,paddr,"ai: special"); return(S_db_noMod); } @@ -268,7 +252,7 @@ static long get_precision(paddr,precision) struct aiRecord *pai=(struct aiRecord *)paddr->precord; *precision = pai->prec; - return(0L); + return(0); } static long get_value(pai,pvdes) @@ -288,7 +272,7 @@ static long get_units(paddr,units) struct aiRecord *pai=(struct aiRecord *)paddr->precord; strncpy(units,pai->egu,sizeof(pai->egu)); - return(0L); + return(0); } static long get_graphic_double(paddr,pgd) @@ -303,7 +287,7 @@ static long get_graphic_double(paddr,pgd) pgd->upper_warning_limit = pai->high; pgd->lower_warning_limit = pai->low; pgd->lower_alarm_limit = pai->lolo; - return(0L); + return(0); } static long get_control_double(paddr,pcd) @@ -314,121 +298,101 @@ static long get_control_double(paddr,pcd) pcd->upper_ctrl_limit = pai->hopr; pcd->lower_ctrl_limit = pai->lopr; - return(0L); + return(0); } -static long alarm(pai) +static void alarm(pai) struct aiRecord *pai; { float ftemp; - /* check for a hardware alarm */ - if (pai->stat == READ_ALARM) return(0); - - /* if in alarm and difference is not > hysterisis don't bother */ - if (pai->stat != NO_ALARM){ - ftemp = pai->lalm - pai->val; - if(ftemp<0.0) ftemp = -ftemp; - if (ftemp < pai->hyst) return(0); - } + /* if difference is not > hysterisis don't bother */ + ftemp = pai->lalm - pai->val; + if(ftemp<0.0) ftemp = -ftemp; + if (ftemp < pai->hyst) return; /* alarm condition hihi */ - if (pai->hhsv != NO_ALARM){ + if (pai->nsevhhsv){ if (pai->val > pai->hihi){ pai->lalm = pai->val; - if (pai->stat != HIHI_ALARM){ - pai->stat = HIHI_ALARM; - pai->sevr = pai->hhsv; - pai->achn = 1; - } - return(0); + pai->nsta = HIHI_ALARM; + pai->nsev = pai->hhsv; + return; } } /* alarm condition lolo */ - if (pai->llsv != NO_ALARM){ + if (pai->nsevllsv){ if (pai->val < pai->lolo){ pai->lalm = pai->val; - if (pai->stat != LOLO_ALARM){ - pai->stat = LOLO_ALARM; - pai->sevr = pai->llsv; - pai->achn = 1; - } - return(0); + pai->nsta = LOLO_ALARM; + pai->nsev = pai->llsv; + return; } } /* alarm condition high */ - if (pai->hsv != NO_ALARM){ + if (pai->nsevhsv){ if (pai->val > pai->high){ pai->lalm = pai->val; - if (pai->stat != HIGH_ALARM){ - pai->stat = HIGH_ALARM; - pai->sevr =pai->hsv; - pai->achn = 1; - } - return(0); + pai->nsta = HIGH_ALARM; + pai->nsev =pai->hsv; + return; } } /* alarm condition lolo */ - if (pai->lsv != NO_ALARM){ + if (pai->nsevlsv){ if (pai->val < pai->low){ pai->lalm = pai->val; - if (pai->stat != LOW_ALARM){ - pai->stat = LOW_ALARM; - pai->sevr = pai->lsv; - pai->achn = 1; - } - return(0); + pai->nsta = LOW_ALARM; + pai->nsev = pai->lsv; + return; } } - - /* no alarm */ - if (pai->stat != NO_ALARM){ - pai->stat = NO_ALARM; - pai->sevr = NO_ALARM; - pai->achn = 1; - } - - return(0); + return; } -static long monitor(pai) +static void monitor(pai) struct aiRecord *pai; { unsigned short monitor_mask; float delta; + short stat,sevr,nsta,nsev; + + /* get previous stat and sevr and new stat and sevr*/ + stat=pai->stat; + sevr=pai->sevr; + nsta=pai->nsta; + nsev=pai->nsev; + /*set current stat and sevr*/ + pai->stat = nsta; + pai->sevr = nsev; + pai->nsta = 0; + pai->nsev = 0; /* anyone waiting for an event on this record */ - if (pai->mlis.count == 0) return(0L); + if (pai->mlis.count == 0) return; /* Flags which events to fire on the value field */ monitor_mask = 0; /* alarm condition changed this scan */ - if (pai->achn){ - /* post events for alarm condition change and value change */ - monitor_mask = DBE_ALARM | DBE_VALUE | DBE_LOG; - - /* post stat and sevr fields */ + if (stat!=nsta || sevr!=nsev) { + /* post events for alarm condition change*/ + monitor_mask = DBE_ALARM; + /* post stat and nsev fields */ db_post_events(pai,&pai->stat,DBE_VALUE); db_post_events(pai,&pai->sevr,DBE_VALUE); - + } + /* check for value change */ + delta = pai->mlst - pai->val; + if(delta<0.0) delta = -delta; + if (delta > pai->mdel) { + /* post events for value change */ + monitor_mask |= DBE_VALUE; /* update last value monitored */ pai->mlst = pai->val; - - /* check for value change */ - }else{ - delta = pai->mlst - pai->val; - if(delta<0.0) delta = -delta; - if (delta > pai->mdel) { - /* post events for value change */ - monitor_mask = DBE_VALUE; - - /* update last value monitored */ - pai->mlst = pai->val; - } } /* check for archive change */ @@ -437,7 +401,6 @@ static long monitor(pai) if (delta > pai->adel) { /* post events on value field for archive change */ monitor_mask |= DBE_LOG; - /* update last archive value monitored */ pai->alst = pai->val; } @@ -447,24 +410,22 @@ static long monitor(pai) db_post_events(pai,&pai->val,monitor_mask); db_post_events(pai,&pai->rval,monitor_mask); } - return(0L); + return; } -static long convert_ai(pai) +static void convert(pai) struct aiRecord *pai; { float val; + val = pai->rval; /* adjust slope and offset */ - if(pai->aslo != 0.0) - val = val * pai->aslo + pai->aoff; - else if(pai->aoff != 0.0) - val = val + pai->aoff; + if(pai->aslo != 0.0) val = val * pai->aslo + pai->aoff; /* convert raw to engineering units and signal units */ if(pai->linr == 0) { - val = pai->val; + ; /* do nothing*/ } else if(pai->linr == 1) { val = (val * pai->eslo) + pai->egul; @@ -476,16 +437,7 @@ struct aiRecord *pai; short lbrk; int number; - val = pai->val; pbrkTable = (struct brkTable *) pai->pbrk; - if((valrawLow) || (val>pbrkTable->rawHigh)) { - if(pai->stat != READ_ALARM) { - pai->stat = READ_ALARM; - pai->sevr = MAJOR_ALARM; - pai->achn = 1; - } - return(0L); - } number = pbrkTable->number; if(pai->init) lbrk = number/2; /* Just start in the middle */ else { @@ -493,21 +445,28 @@ struct aiRecord *pai; /*make sure we dont go off end of table*/ if( (lbrk+1) >= number ) lbrk--; } - pInt = (pbrkTable->papBrkInt[lbrk]); - pnxtInt = (pbrkTable->papBrkInt[lbrk+1]); + pInt = pbrkTable->papBrkInt[lbrk]; + pnxtInt = pbrkTable->papBrkInt[lbrk+1]; /* find entry for increased value */ while( (pnxtInt->raw) <= val ) { if( lbrk >= number-1) { - errMessage(S_db_badField,"breakpoint table error"); - return(S_db_badField); + if(pai->nsev < MAJOR_ALARM) { + pai->nsta = SOFT_ALARM; + pai->nsev = MAJOR_ALARM; + } + break; /* out of while */ } lbrk++; pInt = pbrkTable->papBrkInt[lbrk]; + pnxtInt = pbrkTable->papBrkInt[lbrk+1]; } while( (pInt->raw) > val) { if(lbrk==0) { - errMessage(S_db_badField,"breakpoint table error"); - return(S_db_badField); + if(pai->nsev < MAJOR_ALARM) { + pai->nsta = SOFT_ALARM; + pai->nsev = MAJOR_ALARM; + } + break; /* out of while */ } lbrk--; pInt = pbrkTable->papBrkInt[lbrk]; @@ -517,11 +476,11 @@ struct aiRecord *pai; } /* apply smoothing algorithm */ - if (pai->smoo != 0){ + if (pai->smoo != 0.0){ if (pai->init == 0) pai->val = val; /* initial condition */ pai->val = val * (1.00 - pai->smoo) + (pai->val * pai->smoo); }else{ pai->val = val; } - return(0L); + return; } diff --git a/src/rec/recAo.c b/src/rec/recAo.c index 88e733c9a..9af9ad1ba 100644 --- a/src/rec/recAo.c +++ b/src/rec/recAo.c @@ -1,4 +1,3 @@ - /* recAo.c */ /* share/src/rec $Id$ */ @@ -57,13 +56,13 @@ #include #include -#include #include #include #include #include #include #include +#include #include #include @@ -108,19 +107,26 @@ struct aodset { /* analog input dset */ DEVSUPFUN init; DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ DEVSUPFUN get_ioint_info; - DEVSUPFUN read_ao; - DEVSUPFUN write_ao; + DEVSUPFUN write_ao;/*(0,1)=>success and */ + /*(continue, don`t continue) */ DEVSUPFUN special_linconv; }; /* the following definitions must match those in choiceGbl.ascii */ -#define OUTPUT_FULL 0 +#define SUPERVISORY 0 #define CLOSED_LOOP 1 +/* the following definitions must match those in choiceRec.ascii */ +#define OUTPUT_FULL 0 +#define OUTPUT_INCREMENTAL 1 + /* The following must match the definition in choiceGbl.ascii */ #define LINEAR 1 -long convert_ao(); +void alarm(); +void convert(); +void monitor(); + static long report(fp,paddr) FILE *fp; @@ -148,8 +154,7 @@ static long report(fp,paddr) if(recGblReportGblChoice(fp,pao,"LLSV",pao->llsv)) return(-1); if(fprintf(fp,"HYST %-12.4G ADEL %-12.4G MDEL %-12.4G ESLO %-12.4G\n", pao->hyst,pao->adel,pao->mdel,pao->eslo)) return(-1); - if(fprintf(fp,"RVAL 0x%-8X ACHN %d\n", - pao->rval,pao->achn)) return(-1); + if(fprintf(fp,"RVAL 0x%-8X\n", pao->rval)) return(-1); if(fprintf(fp,"LALM %-12.4G ALST %-12.4G MLST %-12.4G\n", pao->lalm,pao->alst,pao->mlst)) return(-1); return(0); @@ -161,18 +166,22 @@ static long init_record(pao) struct aodset *pdset; long status; + /* initialize so that first alarm, archive, and monitor get generated*/ + pao->lalm = 1e30; + pao->alst = 1e30; + pao->mlst = 1e30; + if(!(pdset = (struct aodset *)(pao->dset))) { recGblRecordError(S_dev_noDSET,pao,"ao: init_record"); return(S_dev_noDSET); } - /* must have read_ao and write_ao function defined */ - if( (pdset->number < 6) || (pdset->read_ao == NULL) ||(pdset->write_ao ==NULL) ) { + /* must have write_ao function defined */ + if( (pdset->number < 6) || (pdset->write_ao ==NULL) ) { recGblRecordError(S_dev_missingSup,pao,"ao: init_record"); return(S_dev_missingSup); } - pao->init = TRUE; if( pdset->init_record ) { - if((status=(*pdset->init_record)(pao))) return(status); + if((status=(*pdset->init_record)(pao,process))) return(status); } /* get the intial value */ if ((pao->dol.type == CONSTANT) && (pao->dol.value.value != 0)){ @@ -187,93 +196,53 @@ static long process(paddr) struct aoRecord *pao=(struct aoRecord *)(paddr->precord); struct aodset *pdset = (struct aodset *)(pao->dset); long status; - long nRequest; - float value; - float diff; if( (pdset==NULL) || (pdset->write_ao==NULL) ) { pao->pact=TRUE; recGblRecordError(S_dev_missingSup,pao,"write_ao"); return(S_dev_missingSup); } - - /* fetch the desired output if there is a database link */ - if ((pao->dol.type == DB_LINK) && (pao->omsl == CLOSED_LOOP)){ - nRequest=1; - if (dbGetLink(&pao->dol.value,DBR_FLOAT,&value,&nRequest) < 0){ - if (pao->stat != READ_ALARM){ - pao->stat = READ_ALARM; - pao->sevr = MAJOR_ALARM; - pao->achn = 1; - } - return(-1); - } - if (pao->oif == OUTPUT_FULL) - pao->val = value; /* output full */ - else - pao->val += value; /* output incremental */ - } - - /* apply the output rate of change */ - if (pao->oroc){ - diff = pao->val - pao->oval; - if (diff < 0){ - if (pao->oroc < -diff){ - pao->oval -= pao->oroc; - }else{ - pao->oval = pao->val; - } - }else if (pao->oroc < diff){ - pao->oval += pao->oroc; - }else{ - pao->oval = pao->val; - } - }else{ - pao->oval = pao->val; - } -/* MARTY check for HW_LIMIT*/ + if(pao->pact == 0) convert(pao); status=(*pdset->write_ao)(pao); /* write the new value */ pao->pact = TRUE; /* status is one if an asynchronous record is being processed*/ - if(status==1) return(1); - else if(status == -1) { - if(pao->stat != READ_ALARM) {/* error. set alarm condition */ - pao->stat = READ_ALARM; - pao->sevr = MAJOR_ALARM; - pao->achn=1; - } - } - else if(status!=0) return(status); - else if(pao->stat == READ_ALARM || pao->stat == HW_LIMIT_ALARM) { - pao->stat = NO_ALARM; - pao->sevr = NO_ALARM; - pao->achn=1; - } - if(status==0) status=convert_ao(pao); -/* MARTY convert_ao_rb */ - - /* report no harware error if previous hardware error */ - if ((pao->stat == READ_ALARM) || (pao->stat == WRITE_ALARM)){ - pao->stat = NO_ALARM; - pao->sevr = NO_ALARM; - pao->achn = 1; - } + if(status==1) return(0); /* check for alarms */ alarm(pao); /* check event list */ - if(!pao->disa) status = monitor(pao); + monitor(pao); /* process the forward scan link record */ - if (pao->flnk.type==DB_LINK) dbScanPassive(&pao->flnk.value); + if (pao->flnk.type==DB_LINK) dbScanPassive(&pao->flnk.value.db_link.pdbAddr); - pao->init=FALSE; pao->pact=FALSE; return(status); } + +static long special(paddr,after) + struct dbAddr *paddr; + int after; +{ + struct aoRecord *pao = (struct aoRecord *)(paddr->precord); + struct aodset *pdset = (struct aodset *) (pao->dset); + int special_type = paddr->special; + + switch(special_type) { + case(SPC_LINCONV): + if(pdset->number<6 || !(pdset->special_linconv)) { + recGblDbaddrError(S_db_noMod,paddr,"ao: special"); + return(S_db_noMod); + } + return((*pdset->special_linconv)(pao,after)); + default: + recGblDbaddrError(S_db_badChoice,paddr,"ao: special"); + return(S_db_badChoice); + } +} static long get_precision(paddr,precision) struct dbAddr *paddr; @@ -282,7 +251,7 @@ static long get_precision(paddr,precision) struct aoRecord *pao=(struct aoRecord *)paddr->precord; *precision = pao->prec; - return(0L); + return(0); } static long get_value(pao,pvdes) @@ -302,7 +271,7 @@ static long get_units(paddr,units) struct aoRecord *pao=(struct aoRecord *)paddr->precord; strncpy(units,pao->egu,sizeof(pao->egu)); - return(0L); + return(0); } static long get_graphic_double(paddr,pgd) @@ -317,7 +286,7 @@ static long get_graphic_double(paddr,pgd) pgd->upper_warning_limit = pao->high; pgd->lower_warning_limit = pao->low; pgd->lower_alarm_limit = pao->lolo; - return(0L); + return(0); } static long get_control_double(paddr,pcd) @@ -328,162 +297,164 @@ static long get_control_double(paddr,pcd) pcd->upper_ctrl_limit = pao->hopr; pcd->lower_ctrl_limit = pao->lopr; - return(0L); + return(0); } -static long alarm(pao) +static void alarm(pao) struct aoRecord *pao; { float ftemp; - /* check for a hardware alarm */ - if (pao->stat == READ_ALARM) return(0); - if (pao->stat == WRITE_ALARM) return(0); - if (pao->stat == HW_LIMIT_ALARM) return(0); + /* if difference is not > hysterisis don't bother */ + ftemp = pao->lalm - pao->val; + if(ftemp<0.0) ftemp = -ftemp; + if (ftemp < pao->hyst) return; - /* if in alarm and difference is not > hysterisis don't bother */ - if (pao->stat != NO_ALARM){ - ftemp = pao->lalm - pao->val; - if(ftemp<0.0) ftemp = -ftemp; - if (ftemp < pao->hyst) return(0); - } + /* alarm condition hihi */ + if (pao->nsevhhsv){ + if (pao->val > pao->hihi){ + pao->lalm = pao->val; + pao->nsta = HIHI_ALARM; + pao->nsev = pao->hhsv; + return; + } + } - /* alarm condition hihi */ - if (pao->hhsv != NO_ALARM){ - if (pao->val > pao->hihi){ - pao->lalm = pao->val; - if (pao->stat != HIHI_ALARM){ - pao->stat = HIHI_ALARM; - pao->sevr = pao->hhsv; - pao->achn = 1; - } - return(0); - } - } + /* alarm condition lolo */ + if (pao->nsevllsv){ + if (pao->val < pao->lolo){ + pao->lalm = pao->val; + pao->nsta = LOLO_ALARM; + pao->nsev = pao->llsv; + return; + } + } - /* alarm condition lolo */ - if (pao->llsv != NO_ALARM){ - if (pao->val < pao->lolo){ - pao->lalm = pao->val; - if (pao->stat != LOLO_ALARM){ - pao->stat = LOLO_ALARM; - pao->sevr = pao->llsv; - pao->achn = 1; - } - return(0); - } - } + /* alarm condition high */ + if (pao->nsevhsv){ + if (pao->val > pao->high){ + pao->lalm = pao->val; + pao->nsta = HIGH_ALARM; + pao->nsev =pao->hsv; + return; + } + } - /* alarm condition high */ - if (pao->hsv != NO_ALARM){ - if (pao->val > pao->high){ - pao->lalm = pao->val; - if (pao->stat != HIGH_ALARM){ - pao->stat = HIGH_ALARM; - pao->sevr =pao->hsv; - pao->achn = 1; - } - return(0); - } - } - - /* alarm condition lolo */ - if (pao->lsv != NO_ALARM){ - if (pao->val < pao->low){ - pao->lalm = pao->val; - if (pao->stat != LOW_ALARM){ - pao->stat = LOW_ALARM; - pao->sevr = pao->lsv; - pao->achn = 1; - } - return(0); - } - } - - /* no alarm */ - if (pao->stat != NO_ALARM){ - pao->stat = NO_ALARM; - pao->sevr = NO_ALARM; - pao->achn = 1; - } - - return(0); + /* alarm condition lolo */ + if (pao->nsevlsv){ + if (pao->val < pao->low){ + pao->lalm = pao->val; + pao->nsta = LOW_ALARM; + pao->nsev = pao->lsv; + return; + } + } + return; } -static long monitor(pao) +static void monitor(pao) struct aoRecord *pao; { unsigned short monitor_mask; float delta; + short stat,sevr,nsta,nsev; + + /* get previous stat and sevr and new stat and sevr*/ + stat=pao->stat; + sevr=pao->sevr; + nsta=pao->nsta; + nsev=pao->nsev; + /*set current stat and sevr*/ + pao->stat = nsta; + pao->sevr = nsev; + pao->nsta = 0; + pao->nsev = 0; /* anyone waiting for an event on this record */ - if (pao->mlis.count == 0) return(0L); + if (pao->mlis.count == 0) return; /* Flags which events to fire on the value field */ monitor_mask = 0; /* alarm condition changed this scan */ - if (pao->achn){ - /* post events for alarm condition change and value change */ - monitor_mask = DBE_ALARM | DBE_VALUE | DBE_LOG; + if (stat!=nsta || sevr!=nsev) { + /* post events for alarm condition change*/ + monitor_mask = DBE_ALARM; + /* post stat and nsev fields */ + db_post_events(pao,&pao->stat,DBE_VALUE); + db_post_events(pao,&pao->sevr,DBE_VALUE); + } + /* check for value change */ + delta = pao->mlst - pao->val; + if(delta<0.0) delta = -delta; + if (delta > pao->mdel) { + /* post events for value change */ + monitor_mask |= DBE_VALUE; + /* update last value monitored */ + pao->mlst = pao->val; + } - /* post stat and sevr fields */ - db_post_events(pao,&pao->stat,DBE_VALUE); - db_post_events(pao,&pao->sevr,DBE_VALUE); + /* check for archive change */ + delta = pao->alst - pao->val; + if(delta<0.0) delta = 0.0; + if (delta > pao->adel) { + /* post events on value field for archive change */ + monitor_mask |= DBE_LOG; + /* update last archive value monitored */ + pao->alst = pao->val; + } - /* update last value monitored */ - pao->mlst = pao->val; - - /* check for value change */ - }else{ - delta = pao->mlst - pao->val; - if(delta<0.0) delta = -delta; - if (delta > pao->mdel) { - /* post events for value change */ - monitor_mask = DBE_VALUE; - - /* update last value monitored */ - pao->mlst = pao->val; - } - } - - /* check for archive change */ - delta = pao->alst - pao->val; - if(delta<0.0) delta = 0.0; - if (delta > pao->adel) { - /* post events on value field for archive change */ - monitor_mask |= DBE_LOG; - - /* update last archive value monitored */ - pao->alst = pao->val; - } - - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(pao,&pao->val,monitor_mask); - db_post_events(pao,&pao->rval,monitor_mask); + /* send out monitors connected to the value field */ + if (monitor_mask){ + db_post_events(pao,&pao->val,monitor_mask); + db_post_events(pao,&pao->rval,monitor_mask); db_post_events(pao,&pao->rbv,monitor_mask); } - return(0L); + return; } -static convert_ao_rb(value,pao) -unsigned short value; /* readback raw value */ -struct aoRecord *pao; -{ - - switch (pao->linr){ - case (LINEAR): - pao->rbv = (value * pao->eslo) + pao->egul; - break; - default: - pao->rbv = value; - } -} - -static convert_ao(pao) +static void convert(pao) struct aoRecord *pao; { + /* fetch the desired output if there is a database link */ + if ((pao->dol.type == DB_LINK) && (pao->omsl == CLOSED_LOOP)){ + long nRequest; + long options; + short save_pact; + float value; + + options=0; + nRequest=1; + save_pact = pao->pact; + pao->pact = TRUE; + (void)dbGetLink(&pao->dol.value,DBR_FLOAT,&value,&options,&nRequest); + if (pao->oif == OUTPUT_FULL) + pao->val = value; /* output full */ + else + pao->val += value; /* output incremental */ + pao->pact = save_pact; + } + + /* apply the output rate of change */ + if (pao->oroc){ + float diff; + + diff = pao->val - pao->oval; + if (diff < 0){ + if (pao->oroc < -diff){ + pao->oval -= pao->oroc; + }else{ + pao->oval = pao->val; + } + }else if (pao->oroc < diff){ + pao->oval += pao->oroc; + }else{ + pao->oval = pao->val; + } + }else{ + pao->oval = pao->val; + } + /* check drive limits */ if (pao->oval > pao->drvh) pao->oval = pao->drvh; else if (pao->oval < pao->drvl) pao->oval = pao->drvl; diff --git a/src/rec/recBi.c b/src/rec/recBi.c index a72fe8cd7..ef1e7736f 100644 --- a/src/rec/recBi.c +++ b/src/rec/recBi.c @@ -1,4 +1,3 @@ - /* recBi.c */ /* share/src/rec $Id$ */ @@ -51,7 +50,6 @@ #include #include -#include #include #include #include @@ -67,8 +65,8 @@ long report(); #define initialize NULL long init_record(); long process(); -long special(); -long get_precision(); +#define special NULL +#define get_precision NULL long get_value(); #define cvt_dbaddr NULL #define get_array_info NULL @@ -78,7 +76,6 @@ long get_enum_str(); #define get_graphic_double NULL #define get_control_double NULL long get_enum_strs(); - struct rset biRSET={ RSETNUMBER, report, @@ -96,7 +93,6 @@ struct rset biRSET={ get_graphic_double, get_control_double, get_enum_strs }; - struct bidset { /* binary input dset */ long number; DEVSUPFUN report; @@ -105,6 +101,9 @@ struct bidset { /* binary input dset */ DEVSUPFUN get_ioint_info; DEVSUPFUN read_bi;/*(-1,0,1)=>(failure,success,don't Continue*/ }; + +void alarm(); +void monitor(); static long report(fp,paddr) FILE *fp; @@ -120,7 +119,8 @@ static long report(fp,paddr) pbi->rval)) return(-1); return(0); } - + + static long init_record(pbi) struct biRecord *pbi; { @@ -137,8 +137,10 @@ static long init_record(pbi) return(S_dev_missingSup); } if( pdset->init_record ) { - if((status=(*pdset->init_record)(pbi))) return(status); + if((status=(*pdset->init_record)(pbi,process))) return(status); } + pbi->mlst = -1; + pbi->lalm = -1; return(0); } @@ -160,29 +162,13 @@ static long process(paddr) /* status is one if an asynchronous record is being processed*/ if(status==1) return(1); - else if(status == -1) { - if(pbi->stat != READ_ALARM) {/* error. set alarm condition */ - pbi->stat = READ_ALARM; - pbi->sevr = MAJOR_ALARM; - pbi->achn=1; - } - } - else if(status!=0) return(status); - else if(pbi->stat == READ_ALARM) { - pbi->stat = NO_ALARM; - pbi->sevr = NO_ALARM; - pbi->achn=1; - } /* check for alarms */ alarm(pbi); - - /* check event list */ - if(!pbi->disa) status = monitor(pbi); - + monitor(pbi); /* process the forward scan link record */ - if (pbi->flnk.type==DB_LINK) dbScanPassive(&pbi->flnk.value); + if (pbi->flnk.type==DB_LINK) dbScanPassive(&pbi->flnk.value.db_link.pdbAddr); pbi->pact=FALSE; return(status); @@ -207,11 +193,11 @@ static long get_enum_str(paddr,pstring) if(pbi->val==0) { strncpy(pstring,pbi->znam,sizeof(pbi->znam)); pstring[sizeof(pbi->znam)] = 0; - } else if(pbi->val==0) { + } else if(pbi->val==1) { strncpy(pstring,pbi->onam,sizeof(pbi->onam)); pstring[sizeof(pbi->onam)] = 0; } else { - strcpy(pstring,"Illegal Value"); + strcpy(pstring,"Illegal_Value"); } return(0L); } @@ -229,89 +215,72 @@ static long get_enum_strs(paddr,pes) return(0L); } -static long alarm(pbi) +static void alarm(pbi) struct biRecord *pbi; { - float ftemp; - /* check for a hardware alarm */ - if (pbi->stat == READ_ALARM) return(0); - - if (pbi->val == pbi->lalm){ - /* no new message for COS alarms */ - if (pbi->stat == COS_ALARM){ - pbi->stat = NO_ALARM; - pbi->sevr = NO_ALARM; - } - return; - } + if (pbi->val == pbi->lalm) return; /* set last alarmed value */ pbi->lalm = pbi->val; /* check for state alarm */ if (pbi->val == 0){ - if (pbi->zsv != NO_ALARM){ - pbi->stat = STATE_ALARM; - pbi->sevr = pbi->zsv; - pbi->achn = 1; - return; + if (pbi->nsevzsv){ + pbi->nsta = STATE_ALARM; + pbi->nsev = pbi->zsv; } }else{ - if (pbi->osv != NO_ALARM){ - pbi->stat = STATE_ALARM; - pbi->sevr = pbi->osv; - pbi->achn = 1; - return; + if (pbi->nsevosv){ + pbi->nsta = STATE_ALARM; + pbi->nsev = pbi->osv; } } /* check for cos alarm */ - if (pbi->cosv != NO_ALARM){ - pbi->sevr = pbi->cosv; - pbi->stat = COS_ALARM; - pbi->achn = 1; - return; + if (pbi->nsevcosv) { + pbi->nsta = COS_ALARM; + pbi->nsev = pbi->cosv; } - /* check for change from alarm to no alarm */ - if (pbi->sevr != NO_ALARM){ - pbi->sevr = NO_ALARM; - pbi->stat = NO_ALARM; - pbi->achn = 1; - return; - } - - return(0); + return; } -static long monitor(pbi) +static void monitor(pbi) struct biRecord *pbi; { unsigned short monitor_mask; + short stat,sevr,nsta,nsev; + + /* get previous stat and sevr and new stat and sevr*/ + stat=pbi->stat; + sevr=pbi->sevr; + nsta=pbi->nsta; + nsev=pbi->nsev; + /*set current stat and sevr*/ + pbi->stat = nsta; + pbi->sevr = nsev; + pbi->nsta = 0; + pbi->nsev = 0; /* anyone waiting for an event on this record */ - if (pbi->mlis.count == 0) return(0L); + if (pbi->mlis.count == 0) return; /* Flags which events to fire on the value field */ monitor_mask = 0; /* alarm condition changed this scan */ - if (pbi->achn){ - /* post events for alarm condition change and value change */ - monitor_mask = DBE_ALARM | DBE_VALUE | DBE_LOG; - + if (stat!=nsta || sevr!=nsev){ + /* post events for alarm condition change*/ + monitor_mask = DBE_ALARM; /* post stat and sevr fields */ db_post_events(pbi,&pbi->stat,DBE_VALUE); db_post_events(pbi,&pbi->sevr,DBE_VALUE); - - /* update last value monitored */ - pbi->mlst = pbi->val; + } /* check for value change */ - }else if (pbi->mlst != pbi->val){ + if (pbi->mlst != pbi->val){ /* post events for value change and archive change */ monitor_mask |= (DBE_VALUE | DBE_LOG); - /* update last value monitored */ pbi->mlst = pbi->val; } @@ -321,5 +290,5 @@ static long monitor(pbi) db_post_events(pbi,&pbi->val,monitor_mask); db_post_events(pbi,&pbi->rval,monitor_mask); } - return(0L); + return; } diff --git a/src/rec/recBo.c b/src/rec/recBo.c index e20397cf8..4f139c5af 100644 --- a/src/rec/recBo.c +++ b/src/rec/recBo.c @@ -1,4 +1,3 @@ - /* recBo.c */ /* share/src/rec $Id$ */ @@ -57,9 +56,9 @@ #include #include #include +#include #include -#include #include #include #include @@ -75,8 +74,8 @@ long report(); #define initialize NULL long init_record(); long process(); -long special(); -long get_precision(); +#define special NULL +#define get_precision NULL long get_value(); #define cvt_dbaddr NULL #define get_array_info NULL @@ -111,13 +110,33 @@ struct bodset { /* binary output dset */ DEVSUPFUN init; DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ DEVSUPFUN get_ioint_info; - DEVSUPFUN read_bo;/*(-1,0)=>(failure,success*/ DEVSUPFUN write_bo;/*(-1,0,1)=>(failure,success,don't Continue*/ }; /* the following definitions must match those in choiceGbl.ascii */ -#define OUTPUT_FULL 0 +#define SUPERVISORY 0 #define CLOSED_LOOP 1 + +/* control block for callback*/ +struct callback { + void (*callback)(); + struct dbAddr dbAddr; + WDOG_ID wd_id; + short completion; +}; + +void callbackRequest(); +void alarm(); +void monitor(); + +static void myCallback(pcallback) + struct callback *pcallback; +{ + short value=0; + + pcallback->completion = TRUE; + dbPutField(&(pcallback->dbAddr),DBR_SHORT,&value,1L); +} static long report(fp,paddr) FILE *fp; @@ -139,13 +158,14 @@ static long init_record(pbo) { struct bodset *pdset; long status; + struct callback *pcallback; if(!(pdset = (struct bodset *)(pbo->dset))) { recGblRecordError(S_dev_noDSET,pbo,"bo: init_record"); return(S_dev_noDSET); } - /* must have read_bo and write_bo functions defined */ - if( (pdset->number < 5) || (pdset->read_bo == NULL) || (pdset->write_bo == NULL) ) { + /* must have write_bo functions defined */ + if( (pdset->number < 5) || (pdset->write_bo == NULL) ) { recGblRecordError(S_dev_missingSup,pbo,"bo: init_record"); return(S_dev_missingSup); } @@ -155,9 +175,15 @@ static long init_record(pbo) else pbo->val = 0; } if( pdset->init_record ) { - if((status=(*pdset->init_record)(pbo))) return(status); + if((status=(*pdset->init_record)(pbo,process))) return(status); + } + pcallback = (struct callback *)(calloc(1,sizeof(struct callback *))); + pbo->dpvt = (caddr_t)pcallback; + pcallback->callback = myCallback; + if(dbNameToAddr(pbo->name,&(pcallback->dbAddr))) { + logMsg("dbNameToAddr failed in init_record for devAiTestAsyn\n"); + exit(1); } - pbo->time = pbo->high * 60; /* seconds to ticks */ pbo->lalm = -1; pbo->mlst = -1; return(0); @@ -170,11 +196,13 @@ static long process(paddr) struct bodset *pdset = (struct bodset *)(pbo->dset); long status; long nRequest; - float fval; + struct callback *pcallback; + int wait_time; + short val; - if( (pdset==NULL) || (pdset->read_bo==NULL) ) { + if( (pdset==NULL) || (pdset->write_bo==NULL) ) { pbo->pact=TRUE; - recGblRecordError(S_dev_missingSup,pbo,"read_bo"); + recGblRecordError(S_dev_missingSup,pbo,"write_bo"); return(S_dev_missingSup); } @@ -182,35 +210,28 @@ static long process(paddr) /* fetch the desired output if there is a database link */ if ( !(pbo->pact) && (pbo->dol.type == DB_LINK) && (pbo->omsl == CLOSED_LOOP)){ nRequest = 1; - if (dbGetLink(&pbo->dol.value,DBF_SHORT,&fval,&nRequest) < 0){ - if (pbo->stat != READ_ALARM){ - pbo->stat = READ_ALARM; - pbo->sevr = MAJOR_ALARM; - pbo->achn = 1; - } - return(-1); - } - if (fval != 0) pbo->val = 1; - else pbo->val = 0; + status = dbGetLink(&pbo->dol.value,DBF_SHORT,&val,&nRequest); + if(status == 0){ + if (val != 0) pbo->val = 1; + else pbo->val = 0; + } } status=(*pdset->write_bo)(pbo); /* write the new value */ pbo->pact = TRUE; /* status is one if an asynchronous record is being processed*/ - if(status==1) return(1); - else if(status == -1) { - if(pbo->stat != WRITE_ALARM) {/* error. set alarm condition */ - pbo->stat = WRITE_ALARM; - pbo->sevr = MAJOR_ALARM; - pbo->achn=1; - } - } - else if(status!=0) return(status); - else if(pbo->stat == WRITE_ALARM) { - pbo->stat = NO_ALARM; - pbo->sevr = NO_ALARM; - pbo->achn=1; + if(status==1) return(0); + + wait_time = (int)(pbo->high) * vxTicksPerSecond; /* seconds to ticks */ + if(pbo->val==1 && wait_time>0) { + pcallback = (struct callback *)(pbo->dpvt); + if(pcallback->completion==TRUE) { + pcallback->completion=FALSE; + } else { + if(pcallback->wd_id==NULL) pcallback->wd_id = wdCreate(); + wdStart(pcallback->wd_id,wait_time,callbackRequest,pcallback); + } } /* check for alarms */ @@ -218,10 +239,10 @@ static long process(paddr) /* check event list */ - if(!pbo->disa) status = monitor(pbo); + monitor(pbo); /* process the forward scan link record */ - if (pbo->flnk.type==DB_LINK) dbScanPassive(&pbo->flnk.value); + if (pbo->flnk.type==DB_LINK) dbScanPassive(&pbo->flnk.value.db_link.pdbAddr); pbo->pact=FALSE; return(status); @@ -246,11 +267,11 @@ static long get_enum_str(paddr,pstring) if(pbo->val==0) { strncpy(pstring,pbo->znam,sizeof(pbo->znam)); pstring[sizeof(pbo->znam)] = 0; - } else if(pbo->val==0) { + } else if(pbo->val==1) { strncpy(pstring,pbo->onam,sizeof(pbo->onam)); pstring[sizeof(pbo->onam)] = 0; } else { - strcpy(pstring,"Illegal Value"); + strcpy(pstring,"Illegal_Value"); } return(0L); } @@ -268,98 +289,81 @@ static long get_enum_strs(paddr,pes) return(0L); } -static long alarm(pbo) +static void alarm(pbo) struct boRecord *pbo; { - float ftemp; - /* check for a hardware alarm */ - if (pbo->stat == WRITE_ALARM || pbo->stat == READ_ALARM) return(0); - - if (pbo->val == pbo->lalm){ - /* no new message for COS alarms */ - if (pbo->stat == COS_ALARM){ - pbo->stat = NO_ALARM; - pbo->sevr = NO_ALARM; - } - return; - } + if (pbo->val == pbo->lalm) return; /* set last alarmed value */ pbo->lalm = pbo->val; /* check for state alarm */ if (pbo->val == 0){ - if (pbo->zsv != NO_ALARM){ - pbo->stat = STATE_ALARM; - pbo->sevr = pbo->zsv; - pbo->achn = 1; - return; + if (pbo->nsevzsv){ + pbo->nsta = STATE_ALARM; + pbo->nsev = pbo->zsv; } }else{ - if (pbo->osv != NO_ALARM){ - pbo->stat = STATE_ALARM; - pbo->sevr = pbo->osv; - pbo->achn = 1; - return; + if (pbo->nsevosv){ + pbo->nsta = STATE_ALARM; + pbo->nsev = pbo->osv; } } /* check for cos alarm */ - if (pbo->cosv != NO_ALARM){ - pbo->sevr = pbo->cosv; - pbo->stat = COS_ALARM; - pbo->achn = 1; - return; + if (pbo->nsevcosv) { + pbo->nsta = COS_ALARM; + pbo->nsev = pbo->cosv; } - /* check for change from alarm to no alarm */ - if (pbo->sevr != NO_ALARM){ - pbo->sevr = NO_ALARM; - pbo->stat = NO_ALARM; - pbo->achn = 1; - return(0); - } - - return(0); + return; } -static long monitor(pbo) +static void monitor(pbo) struct boRecord *pbo; { unsigned short monitor_mask; + short stat,sevr,nsta,nsev; - /* anyone waiting for an event on this record */ - if (pbo->mlis.count == 0) return(0L); + /* get previous stat and sevr and new stat and sevr*/ + stat=pbo->stat; + sevr=pbo->sevr; + nsta=pbo->nsta; + nsev=pbo->nsev; + /*set current stat and sevr*/ + pbo->stat = nsta; + pbo->sevr = nsev; + pbo->nsta = 0; + pbo->nsev = 0; - /* Flags which events to fire on the value field */ - monitor_mask = 0; + /* anyone waiting for an event on this record */ + if (pbo->mlis.count == 0) return; - /* alarm condition changed this scan */ - if (pbo->achn){ - /* post events for alarm condition change and value change */ - monitor_mask = DBE_ALARM | DBE_VALUE | DBE_LOG; + /* Flags which events to fire on the value field */ + monitor_mask = 0; - /* post stat and sevr fields */ - db_post_events(pbo,&pbo->stat,DBE_VALUE); - db_post_events(pbo,&pbo->sevr,DBE_VALUE); - - /* update last value monitored */ - pbo->mlst = pbo->val; + /* alarm condition changed this scan */ + if (stat!=nsta || sevr!=nsev){ + /* post events for alarm condition change*/ + monitor_mask = DBE_ALARM; + /* post stat and sevr fields */ + db_post_events(pbo,&pbo->stat,DBE_VALUE); + db_post_events(pbo,&pbo->sevr,DBE_VALUE); + } /* check for value change */ - }else if (pbo->mlst != pbo->val){ + if (pbo->mlst != pbo->val){ /* post events for value change and archive change */ monitor_mask |= (DBE_VALUE | DBE_LOG); - /* update last value monitored */ pbo->mlst = pbo->val; } - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(pbo,&pbo->val,monitor_mask); - db_post_events(pbo,&pbo->rval,monitor_mask); + /* send out monitors connected to the value field */ + if (monitor_mask){ + db_post_events(pbo,&pbo->val,monitor_mask); + db_post_events(pbo,&pbo->rval,monitor_mask); db_post_events(pbo,&pbo->rbv,monitor_mask); - } - return(0L); + } + return; } diff --git a/src/rec/recCalc.c b/src/rec/recCalc.c index 0d6c72552..a8aeee82c 100644 --- a/src/rec/recCalc.c +++ b/src/rec/recCalc.c @@ -1,4 +1,3 @@ - /* recCalc.c */ /* share/src/rec $Id$ */ @@ -64,11 +63,9 @@ #include #include -#include #include #include #include -#include #include #include #include @@ -109,6 +106,308 @@ struct rset calcRSET={ get_graphic_double, get_control_double, get_enum_strs }; + +void alarm(); +void monitor(); +int do_calc(); +long postfix(); +void fetch_values(); + +static long report(fp,paddr) + FILE *fp; + struct dbAddr *paddr; +{ + struct calcRecord *pcalc=(struct calcRecord*)(paddr->precord); + + if(recGblReportDbCommon(fp,paddr)) return(-1); + if(fprintf(fp,"VAL %-12.4G\n",pcalc->val)) return(-1); + if(recGblReportLink(fp,"INPA ",&(pcalc->inpa))) return(-1); + if(recGblReportLink(fp,"INPB ",&(pcalc->inpb))) return(-1); + if(recGblReportLink(fp,"INPC ",&(pcalc->inpc))) return(-1); + if(recGblReportLink(fp,"INPD ",&(pcalc->inpd))) return(-1); + if(recGblReportLink(fp,"INPE ",&(pcalc->inpe))) return(-1); + if(recGblReportLink(fp,"INPF ",&(pcalc->inpf))) return(-1); + if(recGblReportLink(fp,"FLNK",&(pcalc->flnk))) return(-1); + if(fprintf(fp,"A %-12.4G\n",pcalc->a)) return(-1); + if(fprintf(fp,"B %-12.4G\n",pcalc->b)) return(-1); + if(fprintf(fp,"C %-12.4G\n",pcalc->c)) return(-1); + if(fprintf(fp,"D %-12.4G\n",pcalc->d)) return(-1); + if(fprintf(fp,"E %-12.4G\n",pcalc->e)) return(-1); + if(fprintf(fp,"F %-12.4G\n",pcalc->f)) return(-1); + if(fprintf(fp,"PREC %d EGU %-8s\n",pcalc->prec,pcalc->egu)) return(-1); + if(fprintf(fp,"HOPR %-12.4G LOPR %-12.4G\n", + pcalc->hopr,pcalc->lopr)) return(-1); + if(fprintf(fp,"HIHI %-12.4G HIGH %-12.4G LOW %-12.4G LOLO %-12.4G\n", + pcalc->hihi,pcalc->high,pcalc->low,pcalc->lolo)) return(-1); + if(recGblReportGblChoice(fp,pcalc,"HHSV",pcalc->hhsv)) return(-1); + if(recGblReportGblChoice(fp,pcalc,"HSV ",pcalc->hsv)) return(-1); + if(recGblReportGblChoice(fp,pcalc,"LSV ",pcalc->lsv)) return(-1); + if(recGblReportGblChoice(fp,pcalc,"LLSV",pcalc->llsv)) return(-1); + if(fprintf(fp,"HYST %-12.4G ADEL %-12.4G MDEL %-12.4G\n", + pcalc->hyst,pcalc->adel,pcalc->mdel)) return(-1); + if(fprintf(fp,"LALM %-12.4G ALST %-12.4G MLST %-12.4G\n", + pcalc->lalm,pcalc->alst,pcalc->mlst)) return(-1); + if(fprintf(fp,"CALC %s\n",pcalc->calc)) return(-1); + return(0); +} + +static long init_record(pcalc) + struct calcRecord *pcalc; +{ + long status; + short error_number; + char rpbuf[80]; + + /* initialize so that first alarm, archive, and monitor get generated*/ + pcalc->lalm = 1e30; + pcalc->alst = 1e30; + pcalc->mlst = 1e30; + + if(pcalc->inpa.type==CONSTANT) pcalc->a = pcalc->inpa.value.value; + if(pcalc->inpb.type==CONSTANT) pcalc->b = pcalc->inpb.value.value; + if(pcalc->inpc.type==CONSTANT) pcalc->c = pcalc->inpc.value.value; + if(pcalc->inpd.type==CONSTANT) pcalc->d = pcalc->inpd.value.value; + if(pcalc->inpe.type==CONSTANT) pcalc->e = pcalc->inpe.value.value; + if(pcalc->inpf.type==CONSTANT) pcalc->f = pcalc->inpf.value.value; + status=postfix(pcalc->calc,rpbuf,&error_number); + if(status) return(status); + bcopy(rpbuf,pcalc->rpcl,sizeof(pcalc->rpcl)); + return(0); +} + +static long special(paddr,after) + struct dbAddr *paddr; + int after; +{ + long status; + struct calcRecord *pcalc = (struct calcRecord *)(paddr->precord); + int special_type = paddr->special; + short error_number; + char rpbuf[80]; + + if(!after) return(0); + switch(special_type) { + case(SPC_CALC): + status=postfix(pcalc->calc,rpbuf,&error_number); + if(status) return(status); + bcopy(rpbuf,pcalc->rpcl,sizeof(pcalc->rpcl)); + return(0); + default: + recGblDbaddrError(S_db_badChoice,paddr,"calc: special"); + return(S_db_badChoice); + } +} + +static long get_precision(paddr,precision) + struct dbAddr *paddr; + long *precision; +{ + struct calcRecord *pcalc=(struct calcRecord *)paddr->precord; + + *precision = pcalc->prec; + return(0); +} + +static long get_value(pcalc,pvdes) + struct calcRecord *pcalc; + struct valueDes *pvdes; +{ + pvdes->field_type = DBF_FLOAT; + pvdes->no_elements=1; + (float *)(pvdes->pvalue) = &pcalc->val; + return(0); +} + +static long get_units(paddr,units) + struct dbAddr *paddr; + char *units; +{ + struct calcRecord *pcalc=(struct calcRecord *)paddr->precord; + + strncpy(units,pcalc->egu,sizeof(pcalc->egu)); + return(0); +} + +static long get_graphic_double(paddr,pgd) + struct dbAddr *paddr; + struct dbr_grDouble *pgd; +{ + struct calcRecord *pcalc=(struct calcRecord *)paddr->precord; + + pgd->upper_disp_limit = pcalc->hopr; + pgd->lower_disp_limit = pcalc->lopr; + pgd->upper_alarm_limit = pcalc->hihi; + pgd->upper_warning_limit = pcalc->high; + pgd->lower_warning_limit = pcalc->low; + pgd->lower_alarm_limit = pcalc->lolo; + return(0); +} + +static long get_control_double(paddr,pcd) + struct dbAddr *paddr; + struct dbr_ctrlDouble *pcd; +{ + struct calcRecord *pcalc=(struct calcRecord *)paddr->precord; + + pcd->upper_ctrl_limit = pcalc->hopr; + pcd->lower_ctrl_limit = pcalc->lopr; + return(0); +} + +static long process(paddr) + struct dbAddr *paddr; +{ + struct calcRecord *pcalc=(struct calcRecord *)(paddr->precord); + + pcalc->pact = TRUE; + fetch_values(pcalc); + if(do_calc(pcalc)) { + if(pcalc->nsevnsta = CALC_ALARM; + pcalc->nsev = MAJOR_ALARM; + } + } + if(pcalc->hopr!=pcalc->lopr) { + if(pcalc->val>pcalc->hopr) pcalc->val = pcalc->hopr; + if(pcalc->vallopr) pcalc->val = pcalc->lopr; + } + /* check for alarms */ + alarm(pcalc); + /* check event list */ + monitor(pcalc); + /* process the forward scan link record */ + if (pcalc->flnk.type==DB_LINK) dbScanPassive(&pcalc->flnk.value.db_link.pdbAddr); + pcalc->pact = FALSE; + return(0); +} + +static void alarm(pcalc) + struct calcRecord *pcalc; +{ + float ftemp; + + /* if difference is not > hysterisis don't bother */ + ftemp = pcalc->lalm - pcalc->val; + if(ftemp<0.0) ftemp = -ftemp; + if (ftemp < pcalc->hyst) return; + + /* alarm condition hihi */ + if (pcalc->nsevhhsv){ + if (pcalc->val > pcalc->hihi){ + pcalc->lalm = pcalc->val; + pcalc->nsta = HIHI_ALARM; + pcalc->nsev = pcalc->hhsv; + return; + } + } + + /* alarm condition lolo */ + if (pcalc->nsevllsv){ + if (pcalc->val < pcalc->lolo){ + pcalc->lalm = pcalc->val; + pcalc->nsta = LOLO_ALARM; + pcalc->nsev = pcalc->llsv; + return; + } + } + + /* alarm condition high */ + if (pcalc->nsevhsv){ + if (pcalc->val > pcalc->high){ + pcalc->lalm = pcalc->val; + pcalc->nsta = HIGH_ALARM; + pcalc->nsev =pcalc->hsv; + return; + } + } + + /* alarm condition lolo */ + if (pcalc->nsevlsv){ + if (pcalc->val < pcalc->low){ + pcalc->lalm = pcalc->val; + pcalc->nsta = LOW_ALARM; + pcalc->nsev = pcalc->lsv; + return; + } + } + return; +} + +static void monitor(pcalc) + struct calcRecord *pcalc; +{ + unsigned short monitor_mask; + float delta; + short stat,sevr,nsta,nsev; + + /* get previous stat and sevr and new stat and sevr*/ + stat=pcalc->stat; + sevr=pcalc->sevr; + nsta=pcalc->nsta; + nsev=pcalc->nsev; + /*set current stat and sevr*/ + pcalc->stat = nsta; + pcalc->sevr = nsev; + pcalc->nsta = 0; + pcalc->nsev = 0; + + /* anyone waiting for an event on this record */ + if (pcalc->mlis.count == 0) return; + + /* Flags which events to fire on the value field */ + monitor_mask = 0; + + /* alarm condition changed this scan */ + if (stat!=nsta || sevr!=nsev) { + /* post events for alarm condition change*/ + monitor_mask = DBE_ALARM; + /* post stat and nsev fields */ + db_post_events(pcalc,&pcalc->stat,DBE_VALUE); + db_post_events(pcalc,&pcalc->sevr,DBE_VALUE); + } + /* check for value change */ + delta = pcalc->mlst - pcalc->val; + if(delta<0.0) delta = -delta; + if (delta > pcalc->mdel) { + /* post events for value change */ + monitor_mask |= DBE_VALUE; + /* update last value monitored */ + pcalc->mlst = pcalc->val; + } + /* check for archive change */ + delta = pcalc->alst - pcalc->val; + if(delta<0.0) delta = 0.0; + if (delta > pcalc->adel) { + /* post events on value field for archive change */ + monitor_mask |= DBE_LOG; + /* update last archive value monitored */ + pcalc->alst = pcalc->val; + } + + /* send out monitors connected to the value field */ + if (monitor_mask){ + db_post_events(pcalc,&pcalc->val,monitor_mask); + } + return; +} + +static void fetch_values(pcalc) +struct calcRecord *pcalc; +{ + struct link *plink; /* structure of the link field */ + float *pvalue; + long options,nRequest; + int i; + + for(i=0, plink=&pcalc->inpa, pvalue=&pcalc->a; i<6; i++, plink++, pvalue++) { + if(plink->type!=DB_LINK) continue; + options=0; + nRequest=1; + (void)dbGetLink(&plink->value.db_link,pcalc,DBR_FLOAT, + pvalue,&options,&nRequest); + } + return; +} /* the floating point math routines need to be declared as doubles */ static double random(); /* random number generator */ @@ -172,201 +471,6 @@ double cosh(),sinh(),tanh(); #define PAREN -1 #define END_STACK -1 -static long report(fp,paddr) - FILE *fp; - struct dbAddr *paddr; -{ - struct calcRecord *pcalc=(struct calcRecord*)(paddr->precord); - - if(recGblReportDbCommon(fp,paddr)) return(-1); - if(fprintf(fp,"VAL %-12.4G\n",pcalc->val)) return(-1); - if(recGblReportLink(fp,"INPA ",&(pcalc->inpa))) return(-1); - if(recGblReportLink(fp,"INPB ",&(pcalc->inpb))) return(-1); - if(recGblReportLink(fp,"INPC ",&(pcalc->inpc))) return(-1); - if(recGblReportLink(fp,"INPD ",&(pcalc->inpd))) return(-1); - if(recGblReportLink(fp,"INPE ",&(pcalc->inpe))) return(-1); - if(recGblReportLink(fp,"INPF ",&(pcalc->inpf))) return(-1); - if(recGblReportLink(fp,"FLNK",&(pcalc->flnk))) return(-1); - if(fprintf(fp,"A %-12.4G\n",pcalc->a)) return(-1); - if(fprintf(fp,"B %-12.4G\n",pcalc->b)) return(-1); - if(fprintf(fp,"C %-12.4G\n",pcalc->c)) return(-1); - if(fprintf(fp,"D %-12.4G\n",pcalc->d)) return(-1); - if(fprintf(fp,"E %-12.4G\n",pcalc->e)) return(-1); - if(fprintf(fp,"F %-12.4G\n",pcalc->f)) return(-1); - if(fprintf(fp,"PREC %d EGU %-8s\n",pcalc->prec,pcalc->egu)) return(-1); - if(fprintf(fp,"HOPR %-12.4G LOPR %-12.4G\n", - pcalc->hopr,pcalc->lopr)) return(-1); - if(fprintf(fp,"HIHI %-12.4G HIGH %-12.4G LOW %-12.4G LOLO %-12.4G\n", - pcalc->hihi,pcalc->high,pcalc->low,pcalc->lolo)) return(-1); - if(recGblReportGblChoice(fp,pcalc,"HHSV",pcalc->hhsv)) return(-1); - if(recGblReportGblChoice(fp,pcalc,"HSV ",pcalc->hsv)) return(-1); - if(recGblReportGblChoice(fp,pcalc,"LSV ",pcalc->lsv)) return(-1); - if(recGblReportGblChoice(fp,pcalc,"LLSV",pcalc->llsv)) return(-1); - if(fprintf(fp,"HYST %-12.4G ADEL %-12.4G MDEL %-12.4G\n", - pcalc->hyst,pcalc->adel,pcalc->mdel)) return(-1); - if(fprintf(fp,"ACHN %d\n",pcalc->achn)) return(-1); - if(fprintf(fp,"LALM %-12.4G ALST %-12.4G MLST %-12.4G\n", - pcalc->lalm,pcalc->alst,pcalc->mlst)) return(-1); - if(fprintf(fp,"CALC %s\n",pcalc->calc)) return(-1); - return(0); -} - -static long init_record(pcalc) - struct calcRecord *pcalc; -{ - long status; - short error_number; - char rpbuf[80]; - - if(pcalc->inpa.type==CONSTANT) pcalc->a = pcalc->inpa.value.value; - if(pcalc->inpb.type==CONSTANT) pcalc->b = pcalc->inpb.value.value; - if(pcalc->inpc.type==CONSTANT) pcalc->c = pcalc->inpc.value.value; - if(pcalc->inpd.type==CONSTANT) pcalc->d = pcalc->inpd.value.value; - if(pcalc->inpe.type==CONSTANT) pcalc->e = pcalc->inpe.value.value; - if(pcalc->inpf.type==CONSTANT) pcalc->f = pcalc->inpf.value.value; - status=postfix(pcalc->calc,rpbuf,&error_number); - if(status) return(status); - bcopy(rpbuf,pcalc->rpcl,sizeof(pcalc->rpcl)); - return(0); -} - -static long special(paddr,after) - struct dbAddr *paddr; - int after; -{ - long status; - struct calcRecord *pcalc = (struct calcRecord *)(paddr->precord); - int special_type = paddr->special; - short error_number; - char rpbuf[80]; - - if(!after) return(0); - switch(special_type) { - case(SPC_CALC): - status=postfix(pcalc->calc,rpbuf,&error_number); - if(status) return(status); - bcopy(rpbuf,pcalc->rpcl,sizeof(pcalc->rpcl)); - return(0); - default: - recGblDbaddrError(S_db_badChoice,paddr,"calc: special"); - return(S_db_badChoice); - } -} - -static long get_precision(paddr,precision) - struct dbAddr *paddr; - long *precision; -{ - struct calcRecord *pcalc=(struct calcRecord *)paddr->precord; - - *precision = pcalc->prec; - return(0L); -} - -static long get_value(pcalc,pvdes) - struct calcRecord *pcalc; - struct valueDes *pvdes; -{ - pvdes->field_type = DBF_FLOAT; - pvdes->no_elements=1; - (float *)(pvdes->pvalue) = &pcalc->val; - return(0); -} - -static long get_units(paddr,units) - struct dbAddr *paddr; - char *units; -{ - struct calcRecord *pcalc=(struct calcRecord *)paddr->precord; - - strncpy(units,pcalc->egu,sizeof(pcalc->egu)); - return(0L); -} - -static long get_graphic_double(paddr,pgd) - struct dbAddr *paddr; - struct dbr_grDouble *pgd; -{ - struct calcRecord *pcalc=(struct calcRecord *)paddr->precord; - - pgd->upper_disp_limit = pcalc->hopr; - pgd->lower_disp_limit = pcalc->lopr; - pgd->upper_alarm_limit = pcalc->hihi; - pgd->upper_warning_limit = pcalc->high; - pgd->lower_warning_limit = pcalc->low; - pgd->lower_alarm_limit = pcalc->lolo; - return(0L); -} - -static long get_control_double(paddr,pcd) - struct dbAddr *paddr; - struct dbr_ctrlDouble *pcd; -{ - struct calcRecord *pcalc=(struct calcRecord *)paddr->precord; - - pcd->upper_ctrl_limit = pcalc->hopr; - pcd->lower_ctrl_limit = pcalc->lopr; - return(0L); -} - -static long process(paddr) - struct dbAddr *paddr; -{ - struct calcRecord *pcalc=(struct calcRecord *)(paddr->precord); - struct calcdset *pdset = (struct calcdset *)(pcalc->dset); - long status; - - pcalc->achn = 0; - /* read inputs */ - if (fetch_values(pcalc) < 0){ - if (pcalc->stat != READ_ALARM){ - pcalc->stat = READ_ALARM; - pcalc->sevr = MAJOR_ALARM; - pcalc->achn = 1; - monitor_calc(pcalc); - } - pcalc->pact = 0; - return(0); - }else{ - if (pcalc->stat == READ_ALARM){ - pcalc->stat = NO_ALARM; - pcalc->sevr = NO_ALARM; - pcalc->achn = 1; - } - } - - /* perform calculation */ - if (do_calc(pcalc) < 0){ - if (pcalc->stat != CALC_ALARM){ - pcalc->stat = CALC_ALARM; - pcalc->sevr = MAJOR_ALARM; - pcalc->achn = 1; - monitor_calc(pcalc); - } - pcalc->pact = 0; - return; - }else{ - if (pcalc->stat == CALC_ALARM){ - pcalc->stat = NO_ALARM; - pcalc->sevr = NO_ALARM; - pcalc->achn = 1; - } - } - - /* check for alarms */ - alarm(pcalc); - - - /* check event list */ - if(!pcalc->disa) status = monitor(pcalc); - - /* process the forward scan link record */ - if (pcalc->flnk.type==DB_LINK) dbScanPassive(&pcalc->flnk.value); - - pcalc->pact=FALSE; - return(status); -} - /* * DO_CALC * @@ -376,14 +480,13 @@ static long process(paddr) #define TRUE_COND 1 #define FALSE_COND 2 -static do_calc(pcalc) +static int do_calc(pcalc) struct calcRecord *pcalc; /* pointer to calculation record */ { char *post; /* postfix expression */ double *pstacktop; /* stack of values */ double stack[80]; - double temp; - short temp1; + int temp; short i; double *top; int itop; /* integer top value */ @@ -517,12 +620,12 @@ struct calcRecord *pcalc; /* pointer to calculation record */ case EXPON: --pstacktop; if (*pstacktop < 0){ - temp1 = (int) *(pstacktop+1); + temp = (int) *(pstacktop+1); /* is exponent an integer */ - if ((*(pstacktop+1) - (double)temp1) != 0) return (-1); + if ((*(pstacktop+1) - (double)temp) != 0) return (-1); *pstacktop = exp(*(pstacktop+1) * log(-*pstacktop)); /* is value negative */ - if ((temp1 % 2) > 0) *pstacktop = -*pstacktop; + if ((temp % 2) > 0) *pstacktop = -*pstacktop; }else{ *pstacktop = exp(*(pstacktop+1) * log(*pstacktop)); } @@ -664,62 +767,13 @@ struct calcRecord *pcalc; /* pointer to calculation record */ /* if everything is peachy,the stack should end at its first position */ if (++top == pstacktop) pcalc->val = *pstacktop; - else - return(-1); - return(0); -} - -/* - * FETCH_VALUES - * - * fetch the values for the variables in the calculation - */ -static fetch_values(pcalc) -struct calcRecord *pcalc; -{ - short status; - - /* note - currently not using alarm status */ - status = 0; - status |= get_calc_inp(&pcalc->inpa,&pcalc->a); - status |= get_calc_inp(&pcalc->inpb,&pcalc->b); - status |= get_calc_inp(&pcalc->inpc,&pcalc->c); - status |= get_calc_inp(&pcalc->inpd,&pcalc->d); - status |= get_calc_inp(&pcalc->inpe,&pcalc->e); - status |= get_calc_inp(&pcalc->inpf,&pcalc->f); - return(status); -} - -/* - * GET_CALC_INPUT - * - * return an input value - */ -static get_calc_inp(plink,pvalue) -struct link *plink; /* structure of the link field */ -float *pvalue; -{ - float float_value; - - /* hardware io into a calc not currently supported */ - if (plink->type == VME_IO){ - return(-1); - - /* database link */ - }else if (plink->type == DB_LINK){ - if (dbGetLink(&plink->value.db_link,DBR_FLOAT,&float_value,1) < 0) - return(-1); - *pvalue = float_value; - - /* constant */ - }else if (plink->type == CONSTANT){ - ; - /* illegal link type */ - }else{ - return(-1); + else { + if(pcalc->nsev < MAJOR_ALARM) { + pcalc->nsev = MAJOR_ALARM; + pcalc->nsta = CALC_ALARM; + } } return(0); - } /* @@ -746,135 +800,6 @@ static double random() return(randy); } -static long alarm(pcalc) - struct calcRecord *pcalc; -{ - float ftemp; - - /* if in alarm and difference is not > hysterisis don't bother */ - if (pcalc->stat != NO_ALARM){ - ftemp = pcalc->lalm - pcalc->val; - if(ftemp<0.0) ftemp = -ftemp; - if (ftemp < pcalc->hyst) return(0); - } - - /* alarm condition hihi */ - if (pcalc->hhsv != NO_ALARM){ - if (pcalc->val > pcalc->hihi){ - pcalc->lalm = pcalc->val; - if (pcalc->stat != HIHI_ALARM){ - pcalc->stat = HIHI_ALARM; - pcalc->sevr = pcalc->hhsv; - pcalc->achn = 1; - } - return(0); - } - } - - /* alarm condition lolo */ - if (pcalc->llsv != NO_ALARM){ - if (pcalc->val < pcalc->lolo){ - pcalc->lalm = pcalc->val; - if (pcalc->stat != LOLO_ALARM){ - pcalc->stat = LOLO_ALARM; - pcalc->sevr = pcalc->llsv; - pcalc->achn = 1; - } - return(0); - } - } - - /* alarm condition high */ - if (pcalc->hsv != NO_ALARM){ - if (pcalc->val > pcalc->high){ - pcalc->lalm = pcalc->val; - if (pcalc->stat != HIGH_ALARM){ - pcalc->stat = HIGH_ALARM; - pcalc->sevr =pcalc->hsv; - pcalc->achn = 1; - } - return(0); - } - } - - /* alarm condition lolo */ - if (pcalc->lsv != NO_ALARM){ - if (pcalc->val < pcalc->low){ - pcalc->lalm = pcalc->val; - if (pcalc->stat != LOW_ALARM){ - pcalc->stat = LOW_ALARM; - pcalc->sevr = pcalc->lsv; - pcalc->achn = 1; - } - return(0); - } - } - - /* no alarm */ - if (pcalc->stat != NO_ALARM){ - pcalc->stat = NO_ALARM; - pcalc->sevr = NO_ALARM; - pcalc->achn = 1; - } - - return(0); -} - -static long monitor(pcalc) - struct calcRecord *pcalc; -{ - unsigned short monitor_mask; - float delta; - - /* anyone wcalcting for an event on this record */ - if (pcalc->mlis.count == 0) return(0L); - - /* Flags which events to fire on the value field */ - monitor_mask = 0; - - /* alarm condition changed this scan */ - if (pcalc->achn){ - /* post events for alarm condition change and value change */ - monitor_mask = DBE_ALARM | DBE_VALUE | DBE_LOG; - - /* post stat and sevr fields */ - db_post_events(pcalc,&pcalc->stat,DBE_VALUE); - db_post_events(pcalc,&pcalc->sevr,DBE_VALUE); - - /* update last value monitored */ - pcalc->mlst = pcalc->val; - - /* check for value change */ - }else{ - delta = pcalc->mlst - pcalc->val; - if(delta<0.0) delta = -delta; - if (delta > pcalc->mdel) { - /* post events for value change */ - monitor_mask = DBE_VALUE; - - /* update last value monitored */ - pcalc->mlst = pcalc->val; - } - } - - /* check for archive change */ - delta = pcalc->alst - pcalc->val; - if(delta<0.0) delta = 0.0; - if (delta > pcalc->adel) { - /* post events on value field for archive change */ - monitor_mask |= DBE_LOG; - - /* update last archive value monitored */ - pcalc->alst = pcalc->val; - } - - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(pcalc,&pcalc->val,monitor_mask); - } - return(0L); -} - /* * POSTFIX.C * @@ -933,13 +858,6 @@ static long monitor(pcalc) * FINE found an expression element * VARIABLE found a database reference * UNKNOWN_ELEMENT unknown element found in the infix expression - * match_element finds an alpha element in the expression table - * args - * pbuffer pointer to an alpha expression element - * pelement pointer to the expression element table - * returns - * TRUE found the element in the element table - * FLASE expression element not found * postfix convert an algebraic expression to symbolic postfix * args * pinfix the algebraic expression @@ -1051,7 +969,7 @@ static struct expression_element elements[] = { * * find the pointer to an entry in the element table */ - find_element(pbuffer,pelement,pno_bytes) +static find_element(pbuffer,pelement,pno_bytes) #define SAME 0 char *pbuffer; struct expression_element **pelement; @@ -1076,13 +994,11 @@ static struct expression_element elements[] = { * * get an expression element */ -get_element(pinfix,pelement,pno_bytes) +static get_element(pinfix,pelement,pno_bytes) char *pinfix; struct expression_element **pelement; short *pno_bytes; { - char buffer[40]; - short i; /* get the next expression element from the infix expression */ if (*pinfix == NULL) return(END); @@ -1103,7 +1019,7 @@ short *pno_bytes; * * convert an infix expression to a postfix expression */ -long postfix(pinfix,ppostfix,perror) +static long postfix(pinfix,ppostfix,perror) char *pinfix; char *ppostfix; short *perror; @@ -1113,7 +1029,6 @@ short *perror; short no_bytes; short operand_needed; short new_expression; - short link_inx; /* index into variable table */ struct expression_element stack[80]; struct expression_element *pelement; struct expression_element *pstacktop; diff --git a/src/rec/recCompress.c b/src/rec/recCompress.c index 23232673a..e28f46f58 100644 --- a/src/rec/recCompress.c +++ b/src/rec/recCompress.c @@ -1,4 +1,3 @@ - /* recCompress.c */ /* share/src/rec $Id$ */ @@ -57,15 +56,13 @@ #include #include -#include #include #include #include -#include #include #include -#include #include +#include #include /* Create RSET - Record Support Entry Table*/ @@ -73,7 +70,7 @@ long report(); #define initialize NULL long init_record(); long process(); -#define special NULL +long special(); long get_precision(); long get_value(); long cvt_dbaddr(); @@ -102,12 +99,23 @@ struct rset compressRSET={ get_graphic_double, get_control_double, get_enum_strs }; + +#define NTO1LOW 0 +#define NTO1HIGH 1 +#define NTO1AVG 2 +#define AVERAGE 3 +#define CIRBUF 4 +void alarm(); +void monitor(); +void put_value(); +int compress_array(); +int compress_value(); static long report(fp,paddr) FILE *fp; struct dbAddr *paddr; { - struct compressRecord *pcompress=(struct compressRecord*)(paddr->precord); + struct compressRecord *pcompress=(struct compressRecord*)(paddr->precord); if(recGblReportDbCommon(fp,paddr)) return(-1); return(0); @@ -116,27 +124,51 @@ static long report(fp,paddr) static long init_record(pcompress) struct compressRecord *pcompress; { - long status; /* This routine may get called twice. Once by cvt_dbaddr. Once by iocInit*/ - /* allocate bptr and sptr */ if(pcompress->bptr==NULL) { if(pcompress->nsam<=0) pcompress->nsam=1; - pcompress->bptr = (float *)malloc(pcompress->nsam * sizeof(float)); + pcompress->bptr = (float *)calloc(pcompress->nsam,sizeof(float)); /* allocate memory for the summing buffer for conversions requiring it */ if (pcompress->alg == AVERAGE){ - pcompress->sptr = (float *)malloc(pcompress->nsam * sizeof(float)); + pcompress->sptr = (float *)calloc(pcompress->nsam,sizeof(float)); } } - /*allocate wptr*/ - if(pcompress->wptr==NULL && pcompress->inp.type==PV_LINK) { - struct dbAddr *pdbAddr = (struct dbAddr *)(pcompress->inp.value.db_link.pdbAddr); - pcompress->sptr = (float *)malloc(pdbAddr->no_elements * sizeof(float)); + if(pcompress->wptr==NULL && pcompress->inp.type==DB_LINK) { + struct dbAddr *pdbAddr = (struct dbAddr *)(pcompress->inp.value.db_link.pdbAddr); + + pcompress->wptr = (float *)calloc(pdbAddr->no_elements,sizeof(float)); } - /* initialize the monitor count */ - pcompress->mdct = pcompress->mcnt; + /* initialize all counters */ + pcompress->nuse = 0; + pcompress->off= 0; + pcompress->inx = 0; + pcompress->cvb = 0.0; + pcompress->res = 0; return(0); } + +static long special(paddr,after) + struct dbAddr *paddr; + int after; +{ + struct compressRecord *pcompress = (struct compressRecord *)(paddr->precord); + int special_type = paddr->special; + + if(!after) return(0); + switch(special_type) { + case(SPC_RESET): + pcompress->nuse = 0; + pcompress->off= 0; + pcompress->inx = 0; + pcompress->cvb = 0.0; + pcompress->res = 0; + return(0); + default: + recGblDbaddrError(S_db_badChoice,paddr,"compress: special"); + return(S_db_badChoice); + } +} static long get_precision(paddr,precision) struct dbAddr *paddr; @@ -145,11 +177,11 @@ static long get_precision(paddr,precision) struct compressRecord *pcompress=(struct compressRecord *)paddr->precord; *precision = pcompress->prec; - return(0L); + return(0); } static long get_value(pcompress,pvdes) - struct compressRecord *pcompress; + struct compressRecord *pcompress; struct valueDes *pvdes; { pvdes->field_type = DBF_FLOAT; @@ -164,7 +196,7 @@ static long cvt_dbaddr(paddr) struct compressRecord *pcompress=(struct compressRecord *)paddr->precord; /* This may get called before init_record. If so just call it*/ - if(pcompress->bptr==NULL) init_record(paddr); + if(pcompress->bptr==NULL) (void)init_record(pcompress); paddr->pfield = (caddr_t)(pcompress->bptr); paddr->no_elements = pcompress->nsam; @@ -179,42 +211,40 @@ static long get_array_info(paddr,no_elements,offset) long *no_elements; long *offset; { - struct compressRecord *pcompress=(struct compressRecord *)paddr->precord; + struct compressRecord *pcompress=(struct compressRecord *)paddr->precord; *no_elements = pcompress->nuse; - *offset = inx+1; + *offset = pcompress->off; return(0); } static long put_array_info(paddr,nNew) struct dbAddr *paddr; long nNew; - long offset; { - struct compressRecord *pcompress=(struct compressRecord *)paddr->precord; + struct compressRecord *pcompress=(struct compressRecord *)paddr->precord; - pcompress->inx = (pcompress->inx + nNew) % (pcompress->nsam); + pcompress->off = (pcompress->off + nNew) % (pcompress->nsam); pcompress->nuse = (pcompress->nuse + nNew); if(pcompress->nuse > pcompress->nsam) pcompress->nuse = pcompress->nsam; return(0); } - - + static long get_units(paddr,units) struct dbAddr *paddr; char *units; { - struct compressRecord *pcompress=(struct compressRecord *)paddr->precord; + struct compressRecord *pcompress=(struct compressRecord *)paddr->precord; strncpy(units,pcompress->egu,sizeof(pcompress->egu)); - return(0L); + return(0); } static long get_graphic_double(paddr,pgd) struct dbAddr *paddr; struct dbr_grDouble *pgd; { - struct compressRecord *pcompress=(struct compressRecord *)paddr->precord; + struct compressRecord *pcompress=(struct compressRecord *)paddr->precord; pgd->upper_disp_limit = pcompress->hopr; pgd->lower_disp_limit = pcompress->lopr; @@ -222,277 +252,273 @@ static long get_graphic_double(paddr,pgd) pgd->upper_warning_limit = 0.0; pgd->lower_warning_limit = 0.0; pgd->lower_alarm_limit = 0.0; - return(0L); + return(0); } static long get_control_double(paddr,pcd) struct dbAddr *paddr; struct dbr_ctrlDouble *pcd; { - struct compressRecord *pcompress=(struct compressRecord *)paddr->precord; + struct compressRecord *pcompress=(struct compressRecord *)paddr->precord; - pgd->upper_disp_limit = pcompress->hopr; - pgd->lower_disp_limit = pcompress->lopr; - return(0L); + pcd->upper_ctrl_limit = pcompress->hopr; + pcd->lower_ctrl_limit = pcompress->lopr; + return(0); } static long process(paddr) struct dbAddr *paddr; { - struct compressRecord *pcompress=(struct compressRecord *)(paddr->precord); - struct compressdset *pdset = (struct compressdset *)(pcompress->dset); - long status; + struct compressRecord *pcompress=(struct compressRecord *)(paddr->precord); + long status; + struct dbAddr *pdbAddr = + (struct dbAddr *)(pcompress->inp.value.db_link.pdbAddr); + long options=0; + long no_elements=pdbAddr->no_elements; + int alg=pcompress->alg; - pcompress->achn = 0; - /* read inputs */ - if (do_compression(pcompress) < 0){ - if (pcompress->stat != READ_ALARM){ - pcompress->stat = READ_ALARM; - pcompress->sevr = MAJOR_ALARM; - pcompress->achn = 1; - monitor_compress(pcompress); - } - pcompress->pact = 0; - return(0); - }else{ - if (pcompress->stat == READ_ALARM){ - pcompress->stat = NO_ALARM; - pcompress->sevr = NO_ALARM; - pcompress->achn = 1; + pcompress->pact = TRUE; + + if (pcompress->inp.type != DB_LINK) { + status=0; + }else if (pcompress->wptr == NULL) { + if(pcompress->nsevnsta = READ_ALARM; + pcompress->nsev = MAJOR_ALARM; } + status=0; + } else { + (void)dbGetLink(&pcompress->inp.value.db_link,pcompress,DBR_FLOAT,pcompress->wptr, + &options,&no_elements); + if(alg==AVERAGE) { + status = array_average(pcompress,pcompress->wptr,no_elements); + } else if(alg==CIRBUF) { + (void)put_value(pcompress,pcompress->wptr,no_elements); + status = 0; + } else if(pdbAddr->no_elements>1) { + status = compress_array(pcompress,pcompress->wptr,no_elements); + }else if(no_elements==1){ + status = compress_value(pcompress); + }else status=1; } - /* check event list */ - if(!pcompress->disa) status = monitor(pcompress); - - /* process the forward scan link record */ - if (pcompress->flnk.type==DB_LINK) dbScanPassive(&pcompress->flnk.value); + if(status!=1) { + monitor(pcompress); + /* process the forward scan link record */ + if (pcompress->flnk.type==DB_LINK) dbScanPassive(&pcompress->flnk.value.db_link.pdbAddr); + } pcompress->pact=FALSE; - return(status); -} - -static long monitor(pcompress) - struct compressRecord *pcompress; -{ - unsigned short monitor_mask; - float delta; - - /* anyone wcompressting for an event on this record */ - if (pcompress->mlis.count == 0) return(0L); - - /* Flags which events to fire on the value field */ - monitor_mask = 0; - - /* alarm condition changed this scan */ - if (pcompress->achn){ - /* post events for alarm condition change and value change */ - monitor_mask = DBE_ALARM; - - /* post stat and sevr fields */ - db_post_events(pcompress,&pcompress->stat,DBE_VALUE); - db_post_events(pcompress,&pcompress->sevr,DBE_VALUE); - - /* update last value monitored */ - pcompress->mlst = pcompress->val; - } - monitor_mask |= DBE_LOG|DBE_VALUE; - db_post_events(pcompress,&pcompress->val,monitor_mask); - return(0L); -} - -static long do_compression(pcompress) -struct compress *pcompress; -{ - struct dbAddr *pdbAddr = (struct dbAddr *)(pcompress->inp.value.db_link.pdbAddr); - long options=0; - long no_elements=pdbAddr->no_elements; - - if (pcompress->inp.type != DB_LINK) return(0); - if (pcompress->wptr == NULL) return(-1); - if(status=dbGetLink(&(pcompress->inp),DBR_FLOAT,pcompress->wprt,&options,&no_elements); - - if(pdbAddr->no_elements>1) { - compress_array(pcompress,no_elements); - }else if(no_elements==1){ - compress_value(pcompress); - } return(0); } -compress_array(pcompress,no_elements) -struct compress *pcompress; -long no_elements; +static void monitor(pcompress) + struct compressRecord *pcompress; +{ + unsigned short monitor_mask; + short mdct; + short stat,sevr,nsta,nsev; + + /* get previous stat and sevr and new stat and sevr*/ + stat=pcompress->stat; + sevr=pcompress->sevr; + nsta=pcompress->nsta; + nsev=pcompress->nsev; + /*set current stat and sevr*/ + pcompress->stat = nsta; + pcompress->sevr = nsev; + pcompress->nsta = 0; + pcompress->nsev = 0; + + /* anyone waiting for an event on this record */ + if(pcompress->mlis.count == 0) return; + + /* Flags which events to fire on the value field */ + monitor_mask = 0; + + /* alarm condition changed this scan */ + if (stat!=nsta || sevr!=nsev) { + /* post events for alarm condition change*/ + monitor_mask = DBE_ALARM; + /* post stat and nsev fields */ + db_post_events(pcompress,&pcompress->stat,DBE_VALUE); + db_post_events(pcompress,&pcompress->sevr,DBE_VALUE); + } + monitor_mask |= DBE_LOG|DBE_VALUE; + if(monitor_mask) db_post_events(pcompress,pcompress->bptr,monitor_mask); + return; +} + +static void put_value(pcompress,psource,n) + struct compressRecord *pcompress; + float *psource; + long n; +{ +/* treat bptr as pointer to a circular buffer*/ + float *pdest; + short offset=pcompress->off; + short nuse=pcompress->nuse; + short nsam=pcompress->nsam; + long i; + + pdest = pcompress->bptr + offset; + for(i=0; i=nsam) { + pdest=pcompress->bptr; + offset=0; + } else pdest++; + } + nuse = nuse+n; + if(nuse>nsam) nuse=nsam; + pcompress->off = offset; + pcompress->nuse = nuse; +} + +static int compress_array(pcompress,psource,no_elements) +struct compressRecord *pcompress; +float *psource; +long no_elements; { long i,j; - int buff_size; - float *psource=pcompress->wptr; - short *off=&(pcompress->off); - short nsam=pconpress->nsam; + int nnew; + short nsam=pcompress->nsam; float *pdest; float value; + short n; - /* for all algorithms but AVERAGE apply the front end filter */ - if (pcompress->alg != AVERAGE){ - /* skip out of limit data */ - if ((pcompress->ilil != 0.0) || (pcompress->ihil != 0.0)){ - while (((*psource < pcompress->ilil) - || (*psource > pcompress->ihil)) + /* skip out of limit data */ + if (pcompress->ilil < pcompress->ihil){ + while (((*psource < pcompress->ilil) || (*psource > pcompress->ihil)) && (no_elements > 0)){ no_elements--; psource++; - } } } + if(pcompress->n <= 0) pcompress->n = 1; + n = pcompress->n; + if(no_elementsnsam * pcompress->n)){ - buff_size = (no_elements / pcompress->n); - }else{ - buff_size = pcompress->nsam; - } - - /* destination pointer */ - pdest = pcompress->bptr + pcompress->off; + if (no_elements < (nsam * n)) nnew = (no_elements / n); + else nnew = nsam; /* compress according to specified algorithm */ switch (pcompress->alg){ case (NTO1LOW): /* compress N to 1 keeping the lowest value */ - for (i = 0; i < buff_size; i++){ + for (i = 0; i < nnew; i++){ value = *psource++; for (j = 1; j < pcompress->n; j++, psource++){ - if (value > *psource) - value = *psource; - } - *pdest = value; - if( (*off)++ bptr; - *off=0; + if (value > *psource) value = *psource; } + put_value(pcompress,&value,1); } break; case (NTO1HIGH): /* compress N to 1 keeping the highest value */ - for (i = 0; i < buff_size; i++){ + for (i = 0; i < nnew; i++){ value = *psource++; for (j = 1; j < pcompress->n; j++, psource++){ - if (value < *psource) - value = *psource; - } - *pdest = value; - if( (*off)++ bptr; - *off=0; + if (value < *psource) value = *psource; } + put_value(pcompress,&value,1); } break; case (NTO1AVG): /* compress N to 1 keeping the average value */ - i = 0; - for (i = 0; i < buff_size; i++){ + for (i = 0; i < nnew; i++){ value = 0; - for (j = 0; j < pcompress->n; j++, psource++){ + for (j = 0; j < pcompress->n; j++, psource++) value += *psource; - } - *pdest = value / j; - if( (*off)++ bptr; - *off=0; - } + put_value(pcompress,&value,1); } break; - case (AVERAGE): - { - register float *psum; - register int divider; - - psum = (float *)pcompress->sptr; - - /* add in the new waveform */ - if (pcompress->mdct == pcompress->mcnt || - pcompress->mdct == 0){ - for (i = 0; i < buff_size; i++, psource++, psum++) - *psum = *psource; - }else{ - for (i = 0; i < buff_size; i++, psource++, psum++) - *psum += *psource; - } - - /* do we need to calculate the result */ - if (pcompress->mdct == 1){ - psum = (float *)pcompress->sptr; - divider = pcompress->mcnt; - for (i = 0; i < buff_size; i++, psum++) { - *pdest = *psum / divider; - if( (*off)++ bptr; - *off=0; - } - } - } - break; - } /* end case average */ } - } + return(0); } -static compress_value(pcompress) -register struct compress *pcompress; +static int array_average(pcompress,psource,no_elements) +struct compressRecord *pcompress; +float *psource; +long no_elements; { - float value = *pcompress->wptr;; - short inx; + long i; + int nnow; + short nsam=pcompress->nsam; + float *psum; + float multiplier; + short inx=pcompress->inx; + struct dbAddr *pdbAddr = (struct dbAddr *)(pcompress->inp.value.db_link.pdbAddr); + long ninp=pdbAddr->no_elements; + short nuse,n; + nuse = nsam; + if(nuse>ninp) nuse = ninp; + nnow=nuse; + if(nnow>no_elements) nnow=no_elements; + psum = (float *)pcompress->sptr; - float *pdest; + /* add in the new waveform */ + if (inx == 0){ + for (i = 0; i < nnow; i++) + *psum++ = *psource++; + for(i=nnow; in<=0)pcompress->n=1; + n = pcompress->n; + if(inx1) { + psum = (float *)pcompress->sptr; + multiplier = 1.0/((float)n); + for (i = 0; i < nuse; i++, psum++) + *psum = *psum * multiplier; + } + put_value(pcompress,pcompress->sptr,nuse); + return(0); +} + +static int compress_value(pcompress,psource) +struct compressRecord *pcompress; +float *psource; +{ + float value = *psource; + float *pdest=&pcompress->cvb; + short inx = pcompress->inx; /* compress according to specified algorithm */ switch (pcompress->alg){ case (NTO1LOW): - pdest = pcompress->bptr + pcompress->inx; - if ((value < *pdest) || (pcompress->ccnt == 0)) + if ((value < *pdest) || (inx == 0)) *pdest = value; - pcompress->ccnt++; - if (pcompress->ccnt >= pcompress->n){ - pcompress->ccnt = 0; - if (++pcompress->inx >= pcompress->nsam) - pcompress->inx = 0; - } break; case (NTO1HIGH): - pdest = pcompress->bptr + pcompress->inx; - if ((value > *pdest) || (pcompress->ccnt == 0)) + if ((value > *pdest) || (inx == 0)) *pdest = value; - pcompress->ccnt++; - if (pcompress->ccnt >= pcompress->n){ - pcompress->ccnt = 0; - if (++pcompress->inx >= pcompress->nsam) - pcompress->inx = 0; - } break; case (NTO1AVG): - if (pcompress->ccnt == 0) - pcompress->sum = value; - else - pcompress->sum += value; - pcompress->ccnt++; - if (pcompress->ccnt >= pcompress->n){ - pdest=pcompress->bptr + pcompress->inx; - *pdest = pcompress->sum / pcompress->n; - pcompress->ccnt = 0; - if (++pcompress->inx >= pcompress->nsam) - pcompress->inx = 0; + if (inx == 0) + *pdest = value; + else { + *pdest += value; + if(inx+1>=(pcompress->n)) *pdest = *pdest/(inx+1); } break; } - } + inx++; + if(inx>=pcompress->n) { + put_value(pcompress,pdest,1); + pcompress->inx = 0; + return(0); + } else { + pcompress->inx = inx; + return(1); + } } - diff --git a/src/rec/recFanout.c b/src/rec/recFanout.c index 928e7285e..65469c057 100644 --- a/src/rec/recFanout.c +++ b/src/rec/recFanout.c @@ -1,11 +1,10 @@ - /* recFanout.c */ /* share/src/rec $Id$ */ /* recFanout.c - Record Support Routines for Fanout records * - * Author: Marty Kraimer - * Date: 10/10/90 + * Author: Bob Dalesio + * Date: 12-20-88 * * Control System Software for the GTA Project * @@ -29,7 +28,13 @@ * * Modification Log: * ----------------- - * .01 10-10-90 mrk extensible record and device support + * .01 12-23-88 lrd Alarm on locked MAX_LOCKED times + * .02 05-03-89 lrd removed process mask from arg list + * .03 09-25-89 lrd add conditional scanning + * .04 01-21-90 lrd unlock on scan disable exit + * .05 04-19-90 lrd user select disable on 0 or 1 + * .06 10-31-90 mrk no user select disable on 0 or 1 + * .07 10-31-90 mrk extensible record and device support */ #include @@ -38,11 +43,9 @@ #include #include -#include #include #include #include -#include #include #include #include @@ -55,7 +58,7 @@ long report(); long process(); #define special NULL #define get_precision NULL -long get_value(); +#define get_value NULL #define cvt_dbaddr NULL #define get_array_info NULL #define put_array_info NULL @@ -104,12 +107,13 @@ static long process(paddr) { struct fanoutRecord *pfanout=(struct fanoutRecord *)(paddr->precord); - if (pfanout->lnk1.type==DB_LINK) dbScanPassive(&pfanout->lnk1.value); - if (pfanout->lnk2.type==DB_LINK) dbScanPassive(&pfanout->lnk2.value); - if (pfanout->lnk3.type==DB_LINK) dbScanPassive(&pfanout->lnk3.value); - if (pfanout->lnk4.type==DB_LINK) dbScanPassive(&pfanout->lnk4.value); - if (pfanout->lnk5.type==DB_LINK) dbScanPassive(&pfanout->lnk5.value); - if (pfanout->lnk6.type==DB_LINK) dbScanPassive(&pfanout->lnk6.value); + pfanout->pact = TRUE; + if (pfanout->lnk1.type==DB_LINK) dbScanPassive(&pfanout->lnk1.value.db_link.pdbAddr); + if (pfanout->lnk2.type==DB_LINK) dbScanPassive(&pfanout->lnk2.value.db_link.pdbAddr); + if (pfanout->lnk3.type==DB_LINK) dbScanPassive(&pfanout->lnk3.value.db_link.pdbAddr); + if (pfanout->lnk4.type==DB_LINK) dbScanPassive(&pfanout->lnk4.value.db_link.pdbAddr); + if (pfanout->lnk5.type==DB_LINK) dbScanPassive(&pfanout->lnk5.value.db_link.pdbAddr); + if (pfanout->lnk6.type==DB_LINK) dbScanPassive(&pfanout->lnk6.value.db_link.pdbAddr); pfanout->pact=FALSE; return(0); } diff --git a/src/rec/recMbbi.c b/src/rec/recMbbi.c index 288e87709..7adb063a5 100644 --- a/src/rec/recMbbi.c +++ b/src/rec/recMbbi.c @@ -1,4 +1,3 @@ - /* recMbbi.c */ /* share/src/rec $Id$ */ @@ -44,7 +43,7 @@ * states are defined - like the mbbo * .11 12-06-89 lrd add database fetch support * .12 02-08-90 lrd add Allen-Bradley PLC support - * .13 10-11-90 mrk changes for new record and device support + * .13 10-31-90 mrk changes for new record and device support */ #include @@ -54,7 +53,6 @@ #include #include -#include #include #include #include @@ -70,8 +68,8 @@ long report(); #define initialize NULL long init_record(); long process(); -long special(); -long get_precision(); +long special(); +#define get_precision NULL long get_value(); #define cvt_dbaddr NULL #define get_array_info NULL @@ -108,6 +106,9 @@ struct mbbidset { /* multi bit binary input dset */ DEVSUPFUN get_ioint_info; DEVSUPFUN read_mbbi;/*(-1,0,1)=>(failure,success,don't Continue*/ }; + +void alarm(); +void monitor(); static long report(fp,paddr) FILE *fp; @@ -119,17 +120,37 @@ static long report(fp,paddr) if(fprintf(fp,"VAL %d\n",pmbbi->val)) return(-1); if(recGblReportLink(fp,"INP ",&(pmbbi->inp))) return(-1); if(recGblReportLink(fp,"FLNK",&(pmbbi->flnk))) return(-1); - if(fprintf(fp,"RVAL 0x%-8X\n", - pmbbi->rval)) return(-1); + if(fprintf(fp,"RVAL 0x%-8X\n",pmbbi->rval)) return(-1); return(0); } +static void init_common(pmbbi) + struct mbbiRecord *pmbbi; +{ + unsigned long *pstate_values; + short i; + + /* determine if any states are defined */ + pstate_values = &(pmbbi->zrvl); + pmbbi->sdef = FALSE; + for (i=0; i<16; i++) { + if (*(pstate_values+i)) { + pmbbi->sdef = TRUE; + return; + } + } + return; +} + static long init_record(pmbbi) struct mbbiRecord *pmbbi; { struct mbbidset *pdset; long status; + init_common(pmbbi); + pmbbi->mlst = -1; + pmbbi->lalm = -1; if(!(pdset = (struct mbbidset *)(pmbbi->dset))) { recGblRecordError(S_dev_noDSET,pmbbi,"mbbi: init_record"); return(S_dev_noDSET); @@ -140,79 +161,27 @@ static long init_record(pmbbi) return(S_dev_missingSup); } if( pdset->init_record ) { - if((status=(*pdset->init_record)(pmbbi))) return(status); + if((status=(*pdset->init_record)(pmbbi,process))) return(status); } return(0); } - -static long process(paddr) - struct dbAddr *paddr; + +static long special(paddr,after) + struct dbAddr *paddr; + int after; { - struct mbbiRecord *pmbbi=(struct mbbiRecord *)(paddr->precord); - struct mbbidset *pdset = (struct mbbidset *)(pmbbi->dset); - long status; - unsigned long *pstate_values; - short i,states_defined; + struct mbbiRecord *pmbbi = (struct mbbiRecord *)(paddr->precord); + int special_type = paddr->special; - if( (pdset==NULL) || (pdset->read_mbbi==NULL) ) { - pmbbi->pact=TRUE; - recGblRecordError(S_dev_missingSup,pmbbi,"read_mbbi"); - return(S_dev_missingSup); - } - - status=(*pdset->read_mbbi)(pmbbi); /* read the new value */ - pmbbi->pact = TRUE; - - /* status is one if an asynchronous record is being processed*/ - if(status==1) return(1); - else if(status == -1) { - if(pmbbi->stat != READ_ALARM) {/* error. set alarm condition */ - pmbbi->stat = READ_ALARM; - pmbbi->sevr = MAJOR_ALARM; - pmbbi->achn=1; - } - } - else if(status!=0) return(status); - else if(pmbbi->stat == READ_ALARM) { - pmbbi->stat = NO_ALARM; - pmbbi->sevr = NO_ALARM; - pmbbi->achn=1; - } - - /* determine if any states are defined */ - pstate_values = &(pmbbi->zrvl); - states_defined = 0; - for (i=0; (i<16) && (!states_defined); i++) - if (*(pstate_values+i)) states_defined = 1; - - /* convert the value */ - if (states_defined){ - pstate_values = &(pmbbi->zrvl); - for (i = 0; i < 16; i++){ - if (*pstate_values == pmbbi->rval){ - pmbbi->val = i; - return(0); - } - pstate_values++; - } - pmbbi->val = -2; /* unknown state-other than init LALM */ - }else{ - /* the raw value is the desired value */ - pmbbi->val = pmbbi->rval; - } - - /* check for alarms */ - alarm(pmbbi); - - - /* check event list */ - if(!pmbbi->disa) status = monitor(pmbbi); - - /* process the forward scan link record */ - if (pmbbi->flnk.type==DB_LINK) dbScanPassive(&pmbbi->flnk.value); - - pmbbi->pact=FALSE; - return(status); + if(!after) return(0); + switch(special_type) { + case(SPC_MOD): + init_common(pmbbi); + return(0); + default: + recGblDbaddrError(S_db_badChoice,paddr,"mbbi: special"); + return(S_db_badChoice); + } } static long get_value(pmbbi,pvdes) @@ -233,14 +202,14 @@ static long get_enum_str(paddr,pstring) char *psource; unsigned short val=pmbbi->val; - if( val>0 && val<= 15) { + if(val<= 15) { psource = (pmbbi->zrst); psource += (val * sizeof(pmbbi->zrst)); strncpy(pstring,psource,sizeof(pmbbi->zrst)); } else { strcpy(pstring,"Illegal Value"); } - return(0L); + return(0); } static long get_enum_strs(paddr,pes) @@ -254,103 +223,138 @@ static long get_enum_strs(paddr,pes) pes->no_str = 16; bzero(pes->strs,sizeof(pes->strs)); for(i=0,psource=(pmbbi->zrst); i<15; i++, psource += sizeof(pmbbi->zrst) ) - strncpy(pes->strs[i],pmbbi->zrst,sizeof(pmbbi->zrst)); - return(0L); + strncpy(pes->strs[i],psource,sizeof(pmbbi->zrst)); + return(0); } -static long alarm(pmbbi) +static long process(paddr) + struct dbAddr *paddr; +{ + struct mbbiRecord *pmbbi=(struct mbbiRecord *)(paddr->precord); + struct mbbidset *pdset = (struct mbbidset *)(pmbbi->dset); + long status; + unsigned long *pstate_values; + short i,val; + + if( (pdset==NULL) || (pdset->read_mbbi==NULL) ) { + pmbbi->pact=TRUE; + recGblRecordError(S_dev_missingSup,pmbbi,"read_mbbi"); + return(S_dev_missingSup); + } + + status=(*pdset->read_mbbi)(pmbbi); /* read the new value */ + pmbbi->pact = TRUE; + + /* status is one if an asynchronous record is being processed*/ + if(status==1) return(0); + + /* convert the value */ + if (pmbbi->sdef){ + pstate_values = &(pmbbi->zrvl); + val = -1; /* initalize to unknown state*/ + for (i = 0; i < 16; i++){ + if (*pstate_values == pmbbi->rval){ + val = i; + break; + } + pstate_values++; + } + }else{ + /* the raw value is the desired value */ + *((unsigned short *)(&val)) = (unsigned short)(pmbbi->rval); + } + pmbbi->val = val; + + /* check for alarms */ + alarm(pmbbi); + + + /* check event list */ + monitor(pmbbi); + + /* process the forward scan link record */ + if (pmbbi->flnk.type==DB_LINK) dbScanPassive(&pmbbi->flnk.value.db_link.pdbAddr); + + pmbbi->pact=FALSE; + return(status); +} + +static void alarm(pmbbi) struct mbbiRecord *pmbbi; { - float ftemp; unsigned short *severities; + short val=pmbbi->val; - /* check for a hardware alarm */ - if (pmbbi->stat == READ_ALARM) return(0); - - if (pmbbi->val == pmbbi->lalm){ - /* no new message for COS alarms */ - if (pmbbi->stat == COS_ALARM){ - pmbbi->stat = NO_ALARM; - pmbbi->sevr = NO_ALARM; - } - return; - } - - /* set last alarmed value */ - pmbbi->lalm = pmbbi->val; + if(val = pmbbi->lalm) return; + pmbbi->lalm = val; /* check for state alarm */ /* unknown state */ - if ((pmbbi->val < 0) || (pmbbi->val > 15)){ - if (pmbbi->unsv != NO_ALARM){ - pmbbi->stat = STATE_ALARM; - pmbbi->sevr = pmbbi->unsv; - pmbbi->achn = 1; - return; + if ((val < 0) || (val > 15)){ + if (pmbbi->nsevunsv){ + pmbbi->nsta = STATE_ALARM; + pmbbi->nsev = pmbbi->unsv; } - } - /* in a state which is an error */ - severities = (unsigned short *)&(pmbbi->zrsv); - if (severities[pmbbi->val] != NO_ALARM){ - pmbbi->stat = STATE_ALARM; - pmbbi->sevr = severities[pmbbi->val]; - pmbbi->achn = 1; - return; - } + } else { + /* in a state which is an error */ + severities = (unsigned short *)&(pmbbi->zrsv); + if (pmbbi->nsevval]){ + pmbbi->nsta = STATE_ALARM; + pmbbi->nsev = severities[pmbbi->val]; + } + } /* check for cos alarm */ - if (pmbbi->cosv != NO_ALARM){ - pmbbi->sevr = pmbbi->cosv; - pmbbi->stat = COS_ALARM; - pmbbi->achn = 1; + if (pmbbi->nsevcosv){ + pmbbi->nsta = COS_ALARM; + pmbbi->nsev = pmbbi->cosv; return; } - /* check for change from alarm to no alarm */ - if (pmbbi->sevr != NO_ALARM){ - pmbbi->sevr = NO_ALARM; - pmbbi->stat = NO_ALARM; - pmbbi->achn = 1; - return; - } - - return(0); + return; } -static long monitor(pmbbi) +static void monitor(pmbbi) struct mbbiRecord *pmbbi; { unsigned short monitor_mask; + short stat,sevr,nsta,nsev; + + /* get previous stat and sevr and new stat and sevr*/ + stat=pmbbi->stat; + sevr=pmbbi->sevr; + nsta=pmbbi->nsta; + nsev=pmbbi->nsev; + /*set current stat and sevr*/ + pmbbi->stat = nsta; + pmbbi->sevr = nsev; + pmbbi->nsta = 0; + pmbbi->nsev = 0; /* anyone waiting for an event on this record */ - if (pmbbi->mlis.count == 0) return(0L); + if (pmbbi->mlis.count == 0) return; /* Flags which events to fire on the value field */ monitor_mask = 0; - /* alarm condition changed this scan */ - if (pmbbi->achn){ - /* post events for alarm condition change and value change */ - monitor_mask = DBE_ALARM | DBE_VALUE | DBE_LOG; - - /* post stat and sevr fields */ - db_post_events(pmbbi,&pmbbi->stat,DBE_VALUE); - db_post_events(pmbbi,&pmbbi->sevr,DBE_VALUE); - - /* update last value monitored */ - pmbbi->mlst = pmbbi->val; + /* alarm condition changed this scan */ + if (stat!=nsta || sevr!=nsev){ + /* post events for alarm condition change*/ + monitor_mask = DBE_ALARM; + /* post stat and sevr fields */ + db_post_events(pmbbi,&pmbbi->stat,DBE_VALUE); + db_post_events(pmbbi,&pmbbi->sevr,DBE_VALUE); + } /* check for value change */ - }else if (pmbbi->mlst != pmbbi->val){ + if (pmbbi->mlst != pmbbi->val){ /* post events for value change and archive change */ monitor_mask |= (DBE_VALUE | DBE_LOG); - /* update last value monitored */ pmbbi->mlst = pmbbi->val; } - - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(pmbbi,&pmbbi->val,monitor_mask); - db_post_events(pmbbi,&pmbbi->rval,monitor_mask); - } - return(0L); + /* send out monitors connected to the value field */ + if (monitor_mask){ + db_post_events(pmbbi,&pmbbi->val,monitor_mask); + db_post_events(pmbbi,&pmbbi->rval,monitor_mask); + } + return; } diff --git a/src/rec/recMbbo.c b/src/rec/recMbbo.c index 7608f504b..3bb850d18 100644 --- a/src/rec/recMbbo.c +++ b/src/rec/recMbbo.c @@ -1,4 +1,3 @@ - /* recMbbo.c */ /* share/src/rec $Id$ */ @@ -57,7 +56,6 @@ #include #include -#include #include #include #include @@ -74,7 +72,7 @@ long report(); long init_record(); long process(); long special(); -long get_precision(); +#define get_precision NULL long get_value(); #define cvt_dbaddr NULL #define get_array_info NULL @@ -113,8 +111,11 @@ struct mbbodset { /* multi bit binary input dset */ }; /* the following definitions must match those in choiceGbl.ascii */ -#define OUTPUT_FULL 0 +#define SUPERVISORY 0 #define CLOSED_LOOP 1 + +void alarm(); +void monitor(); static long report(fp,paddr) FILE *fp; @@ -131,11 +132,35 @@ static long report(fp,paddr) return(0); } +static void init_common(pmbbo) + struct mbboRecord *pmbbo; +{ + unsigned long *pstate_values; + short i; + + /* determine if any states are defined */ + pstate_values = &(pmbbo->zrvl); + pmbbo->sdef = FALSE; + for (i=0; i<16; i++) { + if (*(pstate_values+i)) { + pmbbo->sdef = TRUE; + return; + } + } + return; +} + static long init_record(pmbbo) struct mbboRecord *pmbbo; { struct mbbodset *pdset; long status; + unsigned long *pstate_values; + short i,rbv; + + init_common(pmbbo); + pmbbo->mlst = -1; + pmbbo->lalm = -1; if(!(pdset = (struct mbbodset *)(pmbbo->dset))) { recGblRecordError(S_dev_noDSET,pmbbo,"mbbo: init_record"); @@ -147,79 +172,45 @@ static long init_record(pmbbo) return(S_dev_missingSup); } if( pdset->init_record ) { - if((status=(*pdset->init_record)(pmbbo))) return(status); + if((status=(*pdset->init_record)(pmbbo,process))) return(status); + if (pmbbo->sdef){ + pstate_values = &(pmbbo->zrvl); + rbv = -1; /* initalize to unknown state*/ + for (i = 0; i < 16; i++){ + if (*pstate_values == pmbbo->rval){ + rbv = i; + break; + } + pstate_values++; + } + }else{ + /* the raw is the desired rbv */ + rbv = (unsigned short)(pmbbo->rval); + } + pmbbo->rbv = rbv; + pmbbo->val = rbv; } return(0); } -static long process(paddr) - struct dbAddr *paddr; +static long special(paddr,after) + struct dbAddr *paddr; + int after; { - struct mbboRecord *pmbbo=(struct mbboRecord *)(paddr->precord); - struct mbbodset *pdset = (struct mbbodset *)(pmbbo->dset); - long status; - unsigned long *pvalues; - short states_defined,i; + struct mbboRecord *pmbbo = (struct mbboRecord *)(paddr->precord); + int special_type = paddr->special; - if( (pdset==NULL) || (pdset->write_mbbo==NULL) ) { - pmbbo->pact=TRUE; - recGblRecordError(S_dev_missingSup,pmbbo,"write_mbbo"); - return(S_dev_missingSup); - } - - status=(*pdset->write_mbbo)(pmbbo); /* read the new value */ - pmbbo->pact = TRUE; - - /* status is one if an asynchronous record is being processed*/ - if(status==1) return(1); - else if(status == -1) { - if(pmbbo->stat != READ_ALARM) {/* error. set alarm condition */ - pmbbo->stat = READ_ALARM; - pmbbo->sevr = MAJOR_ALARM; - pmbbo->achn=1; - } - } - else if(status!=0) return(status); - else if(pmbbo->stat == READ_ALARM) { - pmbbo->stat = NO_ALARM; - pmbbo->sevr = NO_ALARM; - pmbbo->achn=1; - } - - /* determine if any states are defined */ - pvalues = &(pmbbo->zrvl); - states_defined = FALSE; - for (i=0; (i<16) && (!states_defined); i++) - if (*(pvalues+i)) states_defined = TRUE; - - /* convert the value */ - if (states_defined){ - pvalues = (unsigned long *)&(pmbbo->zrvl); - pmbbo->rbv = -1; /* initialize to unknown state */ - for (i = 0; i < 16; i++,pvalues++){ - if (*pvalues == pmbbo->rval){ - pmbbo->rbv = i; - break; - } - } - }else{ - pmbbo->rbv = pmbbo->rval; - } - - /* check for alarms */ - alarm(pmbbo); - - - /* check event list */ - if(!pmbbo->disa) status = monitor(pmbbo); - - /* process the forward scan link record */ - if (pmbbo->flnk.type==DB_LINK) dbScanPassive(&pmbbo->flnk.value); - - pmbbo->pact=FALSE; - return(status); + if(!after) return(0); + switch(special_type) { + case(SPC_MOD): + init_common(pmbbo); + return(0); + default: + recGblDbaddrError(S_db_badChoice,paddr,"mbbo: special"); + return(S_db_badChoice); + } } - + static long get_value(pmbbo,pvdes) struct mbboRecord *pmbbo; struct valueDes *pvdes; @@ -238,14 +229,14 @@ static long get_enum_str(paddr,pstring) char *psource; unsigned short val=pmbbo->val; - if( val>0 && val<= 15) { + if(val<= 15) { psource = (pmbbo->zrst); psource += (val * sizeof(pmbbo->zrst)); strncpy(pstring,psource,sizeof(pmbbo->zrst)); } else { strcpy(pstring,"Illegal Value"); } - return(0L); + return(0); } static long get_enum_strs(paddr,pes) @@ -259,104 +250,150 @@ static long get_enum_strs(paddr,pes) pes->no_str = 16; bzero(pes->strs,sizeof(pes->strs)); for(i=0,psource=(pmbbo->zrst); i<15; i++, psource += sizeof(pmbbo->zrst) ) - strncpy(pes->strs[i],pmbbo->zrst,sizeof(pmbbo->zrst)); - return(0L); + strncpy(pes->strs[i],psource,sizeof(pmbbo->zrst)); + return(0); } -static long alarm(pmbbo) - struct mbboRecord *pmbbo; +static long process(paddr) + struct dbAddr *paddr; { - float ftemp; - unsigned short *severities; + struct mbboRecord *pmbbo=(struct mbboRecord *)(paddr->precord); + struct mbbodset *pdset = (struct mbbodset *)(pmbbo->dset); + long status; + unsigned long *pstate_values; + short i,rbv; - /* check for a hardware alarm */ - if (pmbbo->stat == READ_ALARM) return(0); - if (pmbbo->stat == WRITE_ALARM) return(0); + if( (pdset==NULL) || (pdset->write_mbbo==NULL) ) { + pmbbo->pact=TRUE; + recGblRecordError(S_dev_missingSup,pmbbo,"write_mbbo"); + return(S_dev_missingSup); + } - if (pmbbo->val == pmbbo->lalm){ - /* no new message for COS alarms */ - if (pmbbo->stat == COS_ALARM){ - pmbbo->stat = NO_ALARM; - pmbbo->sevr = NO_ALARM; - } - return; + /* fetch the desired output if there is a database link */ + if (pmbbo->dol.type == DB_LINK && pmbbo->omsl == CLOSED_LOOP){ + long options=0; + long nRequest=1; + short savepact=pmbbo->pact; + + pmbbo->pact = TRUE; + (void)dbGetLink(&pmbbo->dol.value.db_link,pmbbo,DBR_ENUM, + &(pmbbo->val),&options,&nRequest); + pmbbo->pact = savepact; } - /* set last alarmed value */ - pmbbo->lalm = pmbbo->val; + status=(*pdset->write_mbbo)(pmbbo); /* write the new value */ + pmbbo->pact = TRUE; + + /* status is one if an asynchronous record is being processed*/ + if(status==1) return(0); + + /* convert the value */ + if (pmbbo->sdef){ + pstate_values = &(pmbbo->zrvl); + rbv = -1; /* initalize to unknown state*/ + for (i = 0; i < 16; i++){ + if (*pstate_values == pmbbo->rval){ + rbv = i; + break; + } + pstate_values++; + } + }else{ + /* the raw value is the desired value */ + rbv = (unsigned short)(pmbbo->rval); + } + pmbbo->rbv = rbv; + + /* check for alarms */ + alarm(pmbbo); + + + /* check event list */ + monitor(pmbbo); + + /* process the forward scan link record */ + if (pmbbo->flnk.type==DB_LINK) dbScanPassive(&pmbbo->flnk.value.db_link.pdbAddr); + + pmbbo->pact=FALSE; + return(status); +} + +static void alarm(pmbbo) + struct mbboRecord *pmbbo; +{ + unsigned short *severities; + short val=pmbbo->val; + + if(val = pmbbo->lalm) return; + pmbbo->lalm = val; /* check for state alarm */ /* unknown state */ - if ((pmbbo->val < 0) || (pmbbo->val > 15)){ - if (pmbbo->unsv != NO_ALARM){ - pmbbo->stat = STATE_ALARM; - pmbbo->sevr = pmbbo->unsv; - pmbbo->achn = 1; - return; + if ((val < 0) || (val > 15)){ + if (pmbbo->nsevunsv){ + pmbbo->nsta = STATE_ALARM; + pmbbo->nsev = pmbbo->unsv; } - } - /* in a state which is an error */ - severities = (unsigned short *)&(pmbbo->zrsv); - if (severities[pmbbo->val] != NO_ALARM){ - pmbbo->stat = STATE_ALARM; - pmbbo->sevr = severities[pmbbo->val]; - pmbbo->achn = 1; - return; - } + } else { + /* in a state which is an error */ + severities = (unsigned short *)&(pmbbo->zrsv); + if (pmbbo->nsevval]){ + pmbbo->nsta = STATE_ALARM; + pmbbo->nsev = severities[pmbbo->val]; + } + } /* check for cos alarm */ - if (pmbbo->cosv != NO_ALARM){ - pmbbo->sevr = pmbbo->cosv; - pmbbo->stat = COS_ALARM; - pmbbo->achn = 1; + if (pmbbo->nsevcosv){ + pmbbo->nsta = COS_ALARM; + pmbbo->nsev = pmbbo->cosv; return; } - /* check for change from alarm to no alarm */ - if (pmbbo->sevr != NO_ALARM){ - pmbbo->sevr = NO_ALARM; - pmbbo->stat = NO_ALARM; - pmbbo->achn = 1; - return; - } - - return(0); + return; } -static long monitor(pmbbo) +static void monitor(pmbbo) struct mbboRecord *pmbbo; { unsigned short monitor_mask; + short stat,sevr,nsta,nsev; + + /* get previous stat and sevr and new stat and sevr*/ + stat=pmbbo->stat; + sevr=pmbbo->sevr; + nsta=pmbbo->nsta; + nsev=pmbbo->nsev; + /*set current stat and sevr*/ + pmbbo->stat = nsta; + pmbbo->sevr = nsev; + pmbbo->nsta = 0; + pmbbo->nsev = 0; /* anyone waiting for an event on this record */ - if (pmbbo->mlis.count == 0) return(0L); + if (pmbbo->mlis.count == 0) return; /* Flags which events to fire on the value field */ monitor_mask = 0; - /* alarm condition changed this scan */ - if (pmbbo->achn){ - /* post events for alarm condition change and value change */ - monitor_mask = DBE_ALARM | DBE_VALUE | DBE_LOG; - - /* post stat and sevr fields */ - db_post_events(pmbbo,&pmbbo->stat,DBE_VALUE); - db_post_events(pmbbo,&pmbbo->sevr,DBE_VALUE); - - /* update last value monitored */ - pmbbo->mlst = pmbbo->val; + /* alarm condition changed this scan */ + if (stat!=nsta || sevr!=nsev){ + /* post events for alarm condition change*/ + monitor_mask = DBE_ALARM; + /* post stat and sevr fields */ + db_post_events(pmbbo,&pmbbo->stat,DBE_VALUE); + db_post_events(pmbbo,&pmbbo->sevr,DBE_VALUE); + } /* check for value change */ - }else if (pmbbo->mlst != pmbbo->val){ + if (pmbbo->mlst != pmbbo->val){ /* post events for value change and archive change */ monitor_mask |= (DBE_VALUE | DBE_LOG); - /* update last value monitored */ pmbbo->mlst = pmbbo->val; } - - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(pmbbo,&pmbbo->val,monitor_mask); - db_post_events(pmbbo,&pmbbo->rval,monitor_mask); - } - return(0L); + /* send out monitors connected to the value field */ + if (monitor_mask){ + db_post_events(pmbbo,&pmbbo->val,monitor_mask); + db_post_events(pmbbo,&pmbbo->rval,monitor_mask); + } + return; } diff --git a/src/rec/recPermissive.c b/src/rec/recPermissive.c index 6ae5a046f..50f29c558 100644 --- a/src/rec/recPermissive.c +++ b/src/rec/recPermissive.c @@ -1,4 +1,3 @@ - /* recPermissive.c */ /* share/src/rec $Id$ */ @@ -37,16 +36,12 @@ #include #include -#include -#include #include #include #include -#include #include #include #include -#include #include /* Create RSET - Record Support Entry Table*/ @@ -97,11 +92,24 @@ static long report(fp,paddr) return(0); } +static long get_value(ppermissive,pvdes) + struct permissiveRecord *ppermissive; + struct valueDes *pvdes; +{ + pvdes->field_type = DBF_SHORT; + pvdes->no_elements=1; + (short *)(pvdes->pvalue) = &(ppermissive->val); + return(0); +} + static long process(paddr) struct dbAddr *paddr; { - struct permissiveRecord *ppermissive=(struct permissiveRecord *)(paddr->precord); - /* anyone waiting for an event on this record */ + struct permissiveRecord *ppermissive=(struct permissiveRecord *)(paddr->precord); + + ppermissive->pact=TRUE; + if(ppermissive->mlis.count!=0) + db_post_events(ppermissive,&ppermissive->val,DBE_VALUE); ppermissive->pact=FALSE; return(0); } diff --git a/src/rec/recPid.c b/src/rec/recPid.c index b574279a3..c6104a8d5 100644 --- a/src/rec/recPid.c +++ b/src/rec/recPid.c @@ -1,4 +1,3 @@ - /* recPid.c */ /* share/src/rec $Id$ */ @@ -36,16 +35,16 @@ #include #include #include +/*since tickLib is not defined just define tickGet*/ +unsigned long tickGet(); #include -#include #include #include #include #include #include #include -#include #include /* Create RSET - Record Support Entry Table*/ @@ -83,6 +82,14 @@ struct rset pidRSET={ get_control_double, get_enum_strs }; +/* the following definitions must match those in choiceGbl.ascii */ +#define SUPERVISORY 0 +#define CLOSED_LOOP 1 + +void alarm(); +void monitor(); +long do_pid(); + static long report(fp,paddr) FILE *fp; @@ -92,78 +99,23 @@ static long report(fp,paddr) if(recGblReportDbCommon(fp,paddr)) return(-1); if(fprintf(fp,"VAL %-12.4G\n",ppid->val)) return(-1); - if(recGblReportLink(fp,"INP ",&(ppid->inp))) return(-1); - if(fprintf(fp,"PREC %d\n",ppid->prec)) return(-1); - if(recGblReportCvtChoice(fp,"LINR",ppid->linr)) return(-1); - if(fprintf(fp,"EGUF %-12.4G EGUL %-12.4G EGU %-8s\n", - ppid->eguf,ppid->egul,ppid->egu)) return(-1); - if(fprintf(fp,"HOPR %-12.4G LOPR %-12.4G\n", - ppid->hopr,ppid->lopr)) return(-1); - if(recGblReportLink(fp,"FLNK",&(ppid->flnk))) return(-1); - if(fprintf(fp,"HIHI %-12.4G HIGH %-12.4G LOW %-12.4G LOLO %-12.4G\n", - ppid->hihi,ppid->high,ppid->low,ppid->lolo)) return(-1); - if(recGblReportGblChoice(fp,ppid,"HHSV",ppid->hhsv)) return(-1); - if(recGblReportGblChoice(fp,ppid,"HSV ",ppid->hsv)) return(-1); - if(recGblReportGblChoice(fp,ppid,"LSV ",ppid->lsv)) return(-1); - if(recGblReportGblChoice(fp,ppid,"LLSV",ppid->llsv)) return(-1); - if(fprintf(fp,"HYST %-12.4G ADEL %-12.4G MDEL %-12.4G ESLO %-12.4G\n", - ppid->hyst,ppid->adel,ppid->mdel,ppid->eslo)) return(-1); - if(fprintf(fp,"ACHN %d\n", ppid->achn)) return(-1); - if(fprintf(fp,"LALM %-12.4G ALST %-12.4G MLST %-12.4G\n", - ppid->lalm,ppid->alst,ppid->mlst)) return(-1); return(0); } -^L -static pid_intervals[] = {1,5,4,3,2,1,1,1}; - + static long init_record(ppid) struct pidRecord *ppid; { - /* get the interval based on the scan type */ - ppid->intv = pid_intervals[ppid->scan]; + /* initialize so that first alarm, archive, and monitor get generated*/ + ppid->lalm = 1e30; + ppid->alst = 1e30; + ppid->mlst = 1e30; /* initialize the setpoint for constant setpoint */ if (ppid->stpl.type == CONSTANT) ppid->val = ppid->stpl.value.value; return(0); } - -static long process(paddr) - struct dbAddr *paddr; -{ - struct pidRecord *ppid=(struct pidRecord *)(paddr->precord); - long status; - ppid->pact = TRUE; - status=do_pid(ppid); - if(status == -1) { - if(ppid->stat != READ_ALARM) {/* error. set alarm condition */ - ppid->stat = READ_ALARM; - ppid->sevr = MAJOR_ALARM; - ppid->achn=1; - } - }else if(status!=0) return(status); - else if(ppid->stat == READ_ALARM || ppid->stat == HW_LIMIT_ALARM) { - ppid->stat = NO_ALARM; - ppid->sevr = NO_ALARM; - ppid->achn=1; - } - if(status==0) do_pidect(ppid); - - /* check for alarms */ - alarm(ppid); - - - /* check event list */ - monitor(ppid); - - /* process the forward scan link record */ - if (ppid->flnk.type==DB_LINK) dbScanPassive(&ppid->flnk.value); - - ppid->pact=FALSE; - return(status); -} - static long get_precision(paddr,precision) struct dbAddr *paddr; long *precision; @@ -171,7 +123,7 @@ static long get_precision(paddr,precision) struct pidRecord *ppid=(struct pidRecord *)paddr->precord; *precision = ppid->prec; - return(0L); + return(0); } static long get_value(ppid,pvdes) @@ -183,7 +135,7 @@ static long get_value(ppid,pvdes) (float *)(pvdes->pvalue) = &ppid->val; return(0); } - + static long get_units(paddr,units) struct dbAddr *paddr; char *units; @@ -191,7 +143,7 @@ static long get_units(paddr,units) struct pidRecord *ppid=(struct pidRecord *)paddr->precord; strncpy(units,ppid->egu,sizeof(ppid->egu)); - return(0L); + return(0); } static long get_graphic_double(paddr,pgd) @@ -206,7 +158,7 @@ static long get_graphic_double(paddr,pgd) pgd->upper_warning_limit = ppid->high; pgd->lower_warning_limit = ppid->low; pgd->lower_alarm_limit = ppid->lolo; - return(0L); + return(0); } static long get_control_double(paddr,pcd) @@ -217,7 +169,34 @@ static long get_control_double(paddr,pcd) pcd->upper_ctrl_limit = ppid->hopr; pcd->lower_ctrl_limit = ppid->lopr; - return(0L); + return(0); +} + +static long process(paddr) + struct dbAddr *paddr; +{ + struct pidRecord *ppid=(struct pidRecord *)(paddr->precord); + long status; + + ppid->pact = TRUE; + status=do_pid(ppid); + if(status==1) { + ppid->pact = FALSE; + return(0); + } + + /* check for alarms */ + alarm(ppid); + + + /* check event list */ + monitor(ppid); + + /* process the forward scan link record */ + if (ppid->flnk.type==DB_LINK) dbScanPassive(&ppid->flnk.value.db_link.pdbAddr); + + ppid->pact=FALSE; + return(status); } static void alarm(ppid) @@ -225,76 +204,51 @@ static void alarm(ppid) { float ftemp; - /* check for a hardware alarm */ - if (ppid->stat == READ_ALARM) return(0); + /* if difference is not > hysterisis don't bother */ + ftemp = ppid->lalm - ppid->val; + if(ftemp<0.0) ftemp = -ftemp; + if (ftemp < ppid->hyst) return; - /* if in alarm and difference is not > hysterisis don't bother */ - if (ppid->stat != NO_ALARM){ - ftemp = ppid->lalm - ppid->val; - if(ftemp<0.0) ftemp = -ftemp; - if (ftemp < ppid->hyst) return; - } + /* alarm condition hihi */ + if (ppid->nsevhhsv){ + if (ppid->val > ppid->hihi){ + ppid->lalm = ppid->val; + ppid->nsta = HIHI_ALARM; + ppid->nsev = ppid->hhsv; + return; + } + } - /* alarm condition hihi */ - if (ppid->hhsv != NO_ALARM){ - if (ppid->val > ppid->hihi){ - ppid->lalm = ppid->val; - if (ppid->stat != HIHI_ALARM){ - ppid->stat = HIHI_ALARM; - ppid->sevr = ppid->hhsv; - ppid->achn = 1; - } - return; - } - } + /* alarm condition lolo */ + if (ppid->nsevllsv){ + if (ppid->val < ppid->lolo){ + ppid->lalm = ppid->val; + ppid->nsta = LOLO_ALARM; + ppid->nsev = ppid->llsv; + return; + } + } - /* alarm condition lolo */ - if (ppid->llsv != NO_ALARM){ - if (ppid->val < ppid->lolo){ - ppid->lalm = ppid->val; - if (ppid->stat != LOLO_ALARM){ - ppid->stat = LOLO_ALARM; - ppid->sevr = ppid->llsv; - ppid->achn = 1; - } - return; - } - } + /* alarm condition high */ + if (ppid->nsevhsv){ + if (ppid->val > ppid->high){ + ppid->lalm = ppid->val; + ppid->nsta = HIGH_ALARM; + ppid->nsev =ppid->hsv; + return; + } + } - /* alarm condition high */ - if (ppid->hsv != NO_ALARM){ - if (ppid->val > ppid->high){ - ppid->lalm = ppid->val; - if (ppid->stat != HIGH_ALARM){ - ppid->stat = HIGH_ALARM; - ppid->sevr =ppid->hsv; - ppid->achn = 1; - } - return; - } - } - - /* alarm condition lolo */ - if (ppid->lsv != NO_ALARM){ - if (ppid->val < ppid->low){ - ppid->lalm = ppid->val; - if (ppid->stat != LOW_ALARM){ - ppid->stat = LOW_ALARM; - ppid->sevr = ppid->lsv; - ppid->achn = 1; - } - return; - } - } - - /* no alarm */ - if (ppid->stat != NO_ALARM){ - ppid->stat = NO_ALARM; - ppid->sevr = NO_ALARM; - ppid->achn = 1; - } - - return; + /* alarm condition lolo */ + if (ppid->nsevlsv){ + if (ppid->val < ppid->low){ + ppid->lalm = ppid->val; + ppid->nsta = LOW_ALARM; + ppid->nsev = ppid->lsv; + return; + } + } + return; } static void monitor(ppid) @@ -302,108 +256,160 @@ static void monitor(ppid) { unsigned short monitor_mask; float delta; + short stat,sevr,nsta,nsev; - /* anyone waiting for an event on this record */ - if (ppid->mlis.count == 0) return; + /* get previous stat and sevr and new stat and sevr*/ + stat=ppid->stat; + sevr=ppid->sevr; + nsta=ppid->nsta; + nsev=ppid->nsev; + /*set current stat and sevr*/ + ppid->stat = nsta; + ppid->sevr = nsev; + ppid->nsta = 0; + ppid->nsev = 0; - /* Flags which events to fire on the value field */ - monitor_mask = 0; + /* anyone waiting for an event on this record */ + if (ppid->mlis.count == 0) return; - /* alarm condition changed this scan */ - if (ppid->achn){ - /* post events for alarm condition change and value change */ - monitor_mask = DBE_ALARM | DBE_VALUE | DBE_LOG; + /* Flags which events to fire on the value field */ + monitor_mask = 0; - /* post stat and sevr fields */ - db_post_events(ppid,&ppid->stat,DBE_VALUE); - db_post_events(ppid,&ppid->sevr,DBE_VALUE); - - /* update last value monitored */ - ppid->mlst = ppid->val; - - /* check for value change */ - }else{ - delta = ppid->mlst - ppid->val; - if(delta<0.0) delta = -delta; - if (delta > ppid->mdel) { - /* post events for value change */ - monitor_mask = DBE_VALUE; - - /* update last value monitored */ - ppid->mlst = ppid->val; - } - } - - /* check for archive change */ - delta = ppid->alst - ppid->val; - if(delta<0.0) delta = 0.0; - if (delta > ppid->adel) { - /* post events on value field for archive change */ - monitor_mask |= DBE_LOG; - - /* update last archive value monitored */ - ppid->alst = ppid->val; - } - - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(ppid,&ppid->val,monitor_mask); - db_post_events(ppid,&ppid->rval,monitor_mask); - } - return; -} - -static long do_pid(ppid) -register struct pid *ppid; -{ - /* fetch the controlled value */ - if (ppid->cvl.type != DB_LINK) return(-1); /* nothing to control */ - if (db_fetch(&ppid->cvl.value,&ppid->cval) < 0){ - if (ppid->stat != READ_ALARM){ - ppid->stat = READ_ALARM; - ppid->sevr = MAJOR; - ppid->achn = 1; - return(-1); - } + /* alarm condition changed this scan */ + if (stat!=nsta || sevr!=nsev) { + /* post events for alarm condition change*/ + monitor_mask = DBE_ALARM; + /* post stat and nsev fields */ + db_post_events(ppid,&ppid->stat,DBE_VALUE); + db_post_events(ppid,&ppid->sevr,DBE_VALUE); + } + /* check for value change */ + delta = ppid->mlst - ppid->val; + if(delta<0.0) delta = -delta; + if (delta > ppid->mdel) { + /* post events for value change */ + monitor_mask |= DBE_VALUE; + /* update last value monitored */ + ppid->mlst = ppid->val; + } + /* check for archive change */ + delta = ppid->alst - ppid->val; + if(delta<0.0) delta = 0.0; + if (delta > ppid->adel) { + /* post events on value field for archive change */ + monitor_mask |= DBE_LOG; + /* update last archive value monitored */ + ppid->alst = ppid->val; } -/* rate of change on the setpoint? */ + /* send out monitors connected to the value field */ + if (monitor_mask){ + db_post_events(ppid,&ppid->val,monitor_mask); + } + return; +} + +/* A discrete form of the PID algorithm is as follows + * M(n) = KP*(E(n) + KI*SUMi(E(i)*dT(i)) + * + KD*(E(n) -E(n-1))/dT(i) + Mr + * where + * M(n) Value of manipulated variable at nth sampling instant + * KP,KI,KD Proportional, Integral, and Differential Gains + * NOTE: KI is inverse of normal KI + * E(n) Error at nth sampling instant + * SUMi Sum from i=0 to i=n + * dT(n) Time difference between n-1 and n + * Mr midrange adjustment + * + * Taking first difference yields + * delM(n) = KP*((E(n)-E(n-1)) + E(n)*dT(n)*KI + * + KD*((E(n)-E(n-1))/dT(n) - (E(n-1)-E(n-2))/dT(n-1)) + * or using variables defined in following + * out = kp*(de + e*dt*ki + kd*(de/dt - dep/dtp) + */ + +static long do_pid(ppid) +struct pidRecord *ppid; +{ + long options,nRequest; + unsigned long ctp; /*clock ticks previous */ + unsigned long ct; /*clock ticks */ + float cval; /*actual value */ + float val; /*desired value(setpoint)*/ + float dt; /*delta time (seconds) */ + float dtp; /*previous dt */ + float kp,ki,kd;/*gains */ + float e; /*error */ + float ep; /*previous error */ + float de; /*change in error */ + float dep; /*prev change in error */ + float out; /*output value */ + + /* fetch the controlled value */ + if (ppid->cvl.type != DB_LINK) { /* nothing to control*/ + if (ppid->nsevnsta = SOFT_ALARM; + ppid->nsev = MAJOR_ALARM; + return(0); + } + } + options=0; + nRequest=1; + if(!dbGetLink(&(ppid->cvl.value.db_link),ppid,DBR_FLOAT, + &cval,&options,&nRequest)) { + if (ppid->nsevnsta = READ_ALARM; + ppid->nsev = MAJOR_ALARM; + return(0); + } + } /* fetch the setpoint */ - if ((ppid->stpl.type == DB_LINK) && (ppid->smsl == CLOSED_LOOP)){ - if (db_fetch(&ppid->stpl.value,&ppid->val) < 0){ - if (ppid->stat != READ_ALARM){ + if(ppid->stpl.type == DB_LINK && ppid->smsl == CLOSED_LOOP){ + options=0; + nRequest=1; + if(!dbGetLink(&(ppid->stpl.value.db_link),ppid,DBR_FLOAT, + &(ppid->val),&options,&nRequest)) { + if (ppid->nsevstat = READ_ALARM; - ppid->sevr = MAJOR; - ppid->achn = 1; + ppid->sevr = MAJOR_ALARM; return(-1); } } } + val = ppid->val; - /* reset the integral term when the setpoint changes */ - if (ppid->val != ppid->lval){ - ppid->lval = ppid->val; - ppid->inte = 0; - } - - /* determine the error */ - ppid->lerr = ppid->err; - ppid->err = ppid->val - ppid->cval; - ppid->derr = ppid->err - ppid->lerr; - - /* determine the proportional contribution */ - ppid->prop = ppid->err * ppid->kp; - - /* determine the integral contribution */ - ppid->inte += ppid->err; - ppid->intg = ppid->inte * ppid->ki * ppid->intv; - - /* determine the derivative contribution */ -/* we are implementing the derivativa term on error - do we want value also? */ - ppid->der = (ppid->derr * ppid->kd) / ppid->intv; - - /* delta output contributions weighted by the proportional constant */ - ppid->out = ppid->intg + ppid->der + ppid->prop; - + /* compute time difference and make sure it is large enough*/ + ctp = ppid->ct; + ct = tickGet(); + if(ctp==ct) return(1); + if(ctpmdt) return(1); + /* get the rest of values needed */ + dtp = ppid->dt; + kp = ppid->kp; + ki = ppid->ki; + kd = ppid->kd; + ep = ppid->err; + dep = ppid->derr; + e = val - cval; + de = e - ep; + out = de; + out = out + e*dt*ki; + if(dtp!=0.0) out = out + kd*(de/dt - dep/dtp); + out = kp*out; + /* update record*/ + ppid->ct = ct; + ppid->dt = dt; + ppid->err = e; + ppid->derr = de; + ppid->val = val; + ppid->cval = cval; + ppid->out = out; return(0); } diff --git a/src/rec/recSel.c b/src/rec/recSel.c index 2e7e06404..c1220c1f6 100644 --- a/src/rec/recSel.c +++ b/src/rec/recSel.c @@ -1,4 +1,3 @@ - /* recSel.c */ /* share/src/rec $Id$ */ @@ -41,14 +40,12 @@ #include #include -#include #include #include #include #include #include #include -#include #include /* Create RSET - Record Support Entry Table*/ @@ -87,6 +84,15 @@ struct rset selRSET={ get_enum_strs }; #define SEL_MAX 6 +#define SELECTED 0 +#define SELECT_HIGH 1 +#define SELECT_LOW 2 +#define SELECT_MEDIAN 3 + +void alarm(); +void monitor(); +void fetch_values(); +int do_sel(); static long report(fp,paddr) FILE *fp; @@ -96,31 +102,16 @@ static long report(fp,paddr) if(recGblReportDbCommon(fp,paddr)) return(-1); if(fprintf(fp,"VAL %-12.4G\n",psel->val)) return(-1); - if(recGblReportLink(fp,"INP ",&(psel->inp))) return(-1); - if(fprintf(fp,"PREC %d\n",psel->prec)) return(-1); - if(recGblReportCvtChoice(fp,"LINR",psel->linr)) return(-1); - if(fprintf(fp,"EGUF %-12.4G EGUL %-12.4G EGU %-8s\n", - psel->eguf,psel->egul,psel->egu)) return(-1); - if(fprintf(fp,"HOPR %-12.4G LOPR %-12.4G\n", - psel->hopr,psel->lopr)) return(-1); - if(recGblReportLink(fp,"FLNK",&(psel->flnk))) return(-1); - if(fprintf(fp,"HIHI %-12.4G HIGH %-12.4G LOW %-12.4G LOLO %-12.4G\n", - psel->hihi,psel->high,psel->low,psel->lolo)) return(-1); - if(recGblReportGblChoice(fp,psel,"HHSV",psel->hhsv)) return(-1); - if(recGblReportGblChoice(fp,psel,"HSV ",psel->hsv)) return(-1); - if(recGblReportGblChoice(fp,psel,"LSV ",psel->lsv)) return(-1); - if(recGblReportGblChoice(fp,psel,"LLSV",psel->llsv)) return(-1); - if(fprintf(fp,"HYST %-12.4G ADEL %-12.4G MDEL %-12.4G ESLO %-12.4G\n", - psel->hyst,psel->adel,psel->mdel,psel->eslo)) return(-1); - if(fprintf(fp,"ACHN %d\n", psel->achn)) return(-1); - if(fprintf(fp,"LALM %-12.4G ALST %-12.4G MLST %-12.4G\n", - psel->lalm,psel->alst,psel->mlst)) return(-1); return(0); } -^L + static long init_record(psel) struct selRecord *psel; { + /* initialize so that first alarm, archive, and monitor get generated*/ + psel->lalm = 1e30; + psel->alst = 1e30; + psel->mlst = 1e30; if(psel->inpa.type==CONSTANT) psel->a = psel->inpa.value.value; if(psel->inpb.type==CONSTANT) psel->b = psel->inpb.value.value; @@ -130,43 +121,7 @@ static long init_record(psel) if(psel->inpf.type==CONSTANT) psel->f = psel->inpf.value.value; return(0); } - -static long process(paddr) - struct dbAddr *paddr; -{ - struct selRecord *psel=(struct selRecord *)(paddr->precord); - long status; - psel->pact = TRUE; - status=fetch_values(psel); - if(status == -1) { - if(psel->stat != READ_ALARM) {/* error. set alarm condition */ - psel->stat = READ_ALARM; - psel->sevr = MAJOR_ALARM; - psel->achn=1; - } - }else if(status!=0) return(status); - else if(psel->stat == READ_ALARM || psel->stat == HW_LIMIT_ALARM) { - psel->stat = NO_ALARM; - psel->sevr = NO_ALARM; - psel->achn=1; - } - if(status==0) do_select(psel); - - /* check for alarms */ - alarm(psel); - - - /* check event list */ - if(!psel->disa) status = monitor(psel); - - /* process the forward scan link record */ - if (psel->flnk.type==DB_LINK) dbScanPassive(&psel->flnk.value); - - psel->pact=FALSE; - return(status); -} - static long get_precision(paddr,precision) struct dbAddr *paddr; long *precision; @@ -174,7 +129,7 @@ static long get_precision(paddr,precision) struct selRecord *psel=(struct selRecord *)paddr->precord; *precision = psel->prec; - return(0L); + return(0); } static long get_value(psel,pvdes) @@ -186,7 +141,7 @@ static long get_value(psel,pvdes) (float *)(pvdes->pvalue) = &psel->val; return(0); } - + static long get_units(paddr,units) struct dbAddr *paddr; char *units; @@ -194,7 +149,7 @@ static long get_units(paddr,units) struct selRecord *psel=(struct selRecord *)paddr->precord; strncpy(units,psel->egu,sizeof(psel->egu)); - return(0L); + return(0); } static long get_graphic_double(paddr,pgd) @@ -209,7 +164,7 @@ static long get_graphic_double(paddr,pgd) pgd->upper_warning_limit = psel->high; pgd->lower_warning_limit = psel->low; pgd->lower_alarm_limit = psel->lolo; - return(0L); + return(0); } static long get_control_double(paddr,pcd) @@ -220,144 +175,146 @@ static long get_control_double(paddr,pcd) pcd->upper_ctrl_limit = psel->hopr; pcd->lower_ctrl_limit = psel->lopr; - return(0L); + return(0); } -static long alarm(psel) +static long process(paddr) + struct dbAddr *paddr; +{ + struct selRecord *psel=(struct selRecord *)(paddr->precord); + + psel->pact = TRUE; + fetch_values(psel); + if(!do_sel(psel)) { + if(psel->nsevnsta = CALC_ALARM; + psel->nsev = MAJOR_ALARM; + } + } + + /* check for alarms */ + alarm(psel); + + + /* check event list */ + monitor(psel); + + /* process the forward scan link record */ + if (psel->flnk.type==DB_LINK) dbScanPassive(&psel->flnk.value.db_link.pdbAddr); + + psel->pact=FALSE; + return(0); +} + +static void alarm(psel) struct selRecord *psel; { float ftemp; - /* check for a hardware alarm */ - if (psel->stat == READ_ALARM) return(0); + /* if difference is not > hysterisis don't bother */ + ftemp = psel->lalm - psel->val; + if(ftemp<0.0) ftemp = -ftemp; + if (ftemp < psel->hyst) return; - /* if in alarm and difference is not > hysterisis don't bother */ - if (psel->stat != NO_ALARM){ - ftemp = psel->lalm - psel->val; - if(ftemp<0.0) ftemp = -ftemp; - if (ftemp < psel->hyst) return(0); - } - - /* alarm condition hihi */ - if (psel->hhsv != NO_ALARM){ - if (psel->val > psel->hihi){ - psel->lalm = psel->val; - if (psel->stat != HIHI_ALARM){ - psel->stat = HIHI_ALARM; - psel->sevr = psel->hhsv; - psel->achn = 1; - } - return(0); - } - } - - /* alarm condition lolo */ - if (psel->llsv != NO_ALARM){ - if (psel->val < psel->lolo){ - psel->lalm = psel->val; - if (psel->stat != LOLO_ALARM){ - psel->stat = LOLO_ALARM; - psel->sevr = psel->llsv; - psel->achn = 1; - } - return(0); - } - } - - /* alarm condition high */ - if (psel->hsv != NO_ALARM){ - if (psel->val > psel->high){ - psel->lalm = psel->val; - if (psel->stat != HIGH_ALARM){ - psel->stat = HIGH_ALARM; - psel->sevr =psel->hsv; - psel->achn = 1; - } - return(0); - } - } - - /* alarm condition lolo */ - if (psel->lsv != NO_ALARM){ - if (psel->val < psel->low){ - psel->lalm = psel->val; - if (psel->stat != LOW_ALARM){ - psel->stat = LOW_ALARM; - psel->sevr = psel->lsv; - psel->achn = 1; - } - return(0); - } - } - - /* no alarm */ - if (psel->stat != NO_ALARM){ - psel->stat = NO_ALARM; - psel->sevr = NO_ALARM; - psel->achn = 1; - } - - return(0); + /* alarm condition hihi */ + if (psel->nsevhhsv){ + if (psel->val > psel->hihi){ + psel->lalm = psel->val; + psel->nsta = HIHI_ALARM; + psel->nsev = psel->hhsv; + return; + } + } + /* alarm condition lolo */ + if (psel->nsevllsv){ + if (psel->val < psel->lolo){ + psel->lalm = psel->val; + psel->nsta = LOLO_ALARM; + psel->nsev = psel->llsv; + return; + } + } + /* alarm condition high */ + if (psel->nsevhsv){ + if (psel->val > psel->high){ + psel->lalm = psel->val; + psel->nsta = HIGH_ALARM; + psel->nsev =psel->hsv; + return; + } + } + /* alarm condition lolo */ + if (psel->nsevlsv){ + if (psel->val < psel->low){ + psel->lalm = psel->val; + psel->nsta = LOW_ALARM; + psel->nsev = psel->lsv; + return; + } + } + return; } -static long monitor(psel) +static void monitor(psel) struct selRecord *psel; { unsigned short monitor_mask; float delta; + short stat,sevr,nsta,nsev; - /* anyone waiting for an event on this record */ - if (psel->mlis.count == 0) return(0L); + /* get previous stat and sevr and new stat and sevr*/ + stat=psel->stat; + sevr=psel->sevr; + nsta=psel->nsta; + nsev=psel->nsev; + /*set current stat and sevr*/ + psel->stat = nsta; + psel->sevr = nsev; + psel->nsta = 0; + psel->nsev = 0; - /* Flags which events to fire on the value field */ - monitor_mask = 0; + /* anyone waiting for an event on this record */ + if (psel->mlis.count == 0) return; - /* alarm condition changed this scan */ - if (psel->achn){ - /* post events for alarm condition change and value change */ - monitor_mask = DBE_ALARM | DBE_VALUE | DBE_LOG; + /* Flags which events to fire on the value field */ + monitor_mask = 0; - /* post stat and sevr fields */ - db_post_events(psel,&psel->stat,DBE_VALUE); - db_post_events(psel,&psel->sevr,DBE_VALUE); + /* alarm condition changed this scan */ + if (stat!=nsta || sevr!=nsev) { + /* post events for alarm condition change*/ + monitor_mask = DBE_ALARM; + /* post stat and nsev fields */ + db_post_events(psel,&psel->stat,DBE_VALUE); + db_post_events(psel,&psel->sevr,DBE_VALUE); + } + /* check for value change */ + delta = psel->mlst - psel->val; + if(delta<0.0) delta = -delta; + if (delta > psel->mdel) { + /* post events for value change */ + monitor_mask |= DBE_VALUE; + /* update last value monitored */ + psel->mlst = psel->val; + } + /* check for archive change */ + delta = psel->alst - psel->val; + if(delta<0.0) delta = 0.0; + if (delta > psel->adel) { + /* post events on value field for archive change */ + monitor_mask |= DBE_LOG; + /* update last archive value monitored */ + psel->alst = psel->val; + } - /* update last value monitored */ - psel->mlst = psel->val; - - /* check for value change */ - }else{ - delta = psel->mlst - psel->val; - if(delta<0.0) delta = -delta; - if (delta > psel->mdel) { - /* post events for value change */ - monitor_mask = DBE_VALUE; - - /* update last value monitored */ - psel->mlst = psel->val; - } - } - - /* check for archive change */ - delta = psel->alst - psel->val; - if(delta<0.0) delta = 0.0; - if (delta > psel->adel) { - /* post events on value field for archive change */ - monitor_mask |= DBE_LOG; - - /* update last archive value monitored */ - psel->alst = psel->val; - } - - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(psel,&psel->val,monitor_mask); - db_post_events(psel,&psel->rval,monitor_mask); - } - return(0L); + /* send out monitors connected to the value field */ + if (monitor_mask){ + db_post_events(psel,&psel->val,monitor_mask); + } + return; } -static long do_sel(psel) -struct sel *psel; /* pointer to selection record */ +static int do_sel(psel) +struct selRecord *psel; /* pointer to selection record */ { float *pvalue; struct link *plink; @@ -402,6 +359,8 @@ struct sel *psel; /* pointer to selection record */ } psel->val = order[order_inx/2]; break; + default: + return(-1); } /* initialize flag */ @@ -413,22 +372,22 @@ struct sel *psel; /* pointer to selection record */ * * fetch the values for the variables from which to select */ -static fetch_values(psel) -register struct sel *psel; +static void fetch_values(psel) +struct selRecord *psel; { long nRequest; long options=0; struct link *plink; float *pvalue; + int i; plink = &psel->inpa; pvalue = &psel->a; for(i=0; itype==DB_LINK) { nRequest=1; - status=dbGetLink(plink,DBR_FLOAT,pvalue,&options,&nRequest); - if(status!=0) return(status); + (void)dbGetLink(&plink->value.db_link,psel,DBR_FLOAT,pvalue,&options,&nRequest); } } - return(0); + return; } diff --git a/src/rec/recState.c b/src/rec/recState.c index 464b4bb92..b9e4138ea 100644 --- a/src/rec/recState.c +++ b/src/rec/recState.c @@ -1,4 +1,3 @@ - /* recState.c */ /* share/src/rec $Id$ */ @@ -37,8 +36,6 @@ #include #include -#include -#include #include #include #include @@ -46,7 +43,6 @@ #include #include #include -#include #include /* Create RSET - Record Support Entry Table*/ @@ -91,15 +87,29 @@ static long report(fp,paddr) struct stateRecord *pstate=(struct stateRecord*)(paddr->precord); if(recGblReportDbCommon(fp,paddr)) return(-1); - if(fprintf(fp,"VAL %d\n",pstate->val)) return(-1); + if(fprintf(fp,"VAL %s\n",pstate->val)) return(-1); return(0); } +static long get_value(pstate,pvdes) + struct stateRecord *pstate; + struct valueDes *pvdes; +{ + pvdes->field_type = DBF_STRING; + pvdes->no_elements=1; + pvdes->pvalue = (caddr_t)(&pstate->val[0]); + return(0); +} + + static long process(paddr) struct dbAddr *paddr; { - struct stateRecord *pstate=(struct stateRecord *)(paddr->precord); - /* anyone waiting for an event on this record */ - pstate->pact=FALSE; + struct stateRecord *pstate=(struct stateRecord *)(paddr->precord); + + pstate->pact=TRUE; + if(pstate->mlis.count != 0) + db_post_events(pstate,&(pstate->val[0]),DBE_VALUE); + pstate->pact=FALSE; return(0); } diff --git a/src/rec/recSub.c b/src/rec/recSub.c index 8245bbe43..0a2ef42a9 100644 --- a/src/rec/recSub.c +++ b/src/rec/recSub.c @@ -1,4 +1,3 @@ - /* recSub.c */ /* share/src/rec $Id$ */ @@ -35,17 +34,18 @@ #include #include #include +#include +#include +#include /* for sysSymTbl*/ +#include /* for N_TEXT */ #include -#include #include #include #include -#include #include #include #include -#include #include /* Create RSET - Record Support Entry Table*/ @@ -82,6 +82,11 @@ struct rset subRSET={ get_graphic_double, get_control_double, get_enum_strs }; + +void alarm(); +void monitor(); +long do_sub(); +void fetch_values(); static long report(fp,paddr) FILE *fp; @@ -115,21 +120,19 @@ static long report(fp,paddr) if(recGblReportGblChoice(fp,psub,"LLSV",psub->llsv)) return(-1); if(fprintf(fp,"HYST %-12.4G ADEL %-12.4G MDEL %-12.4G\n", psub->hyst,psub->adel,psub->mdel)) return(-1); - if(fprintf(fp,"ACHN %d\n",psub->achn)) return(-1); if(fprintf(fp,"LALM %-12.4G ALST %-12.4G MLST %-12.4G\n", psub->lalm,psub->alst,psub->mlst)) return(-1); - if(fprintf(fp,"CALC %s\n",psub->sub)) return(-1); return(0); } static long init_record(psub) struct subRecord *psub; { - long status; FUNCPTR psubroutine; char sub_type; char temp[40]; - short ret; + long status; + STATUS ret; if(psub->inpa.type==CONSTANT) psub->a = psub->inpa.value.value; if(psub->inpb.type==CONSTANT) psub->b = psub->inpb.value.value; @@ -146,27 +149,15 @@ static long init_record(psub) } strcat(temp,psub->inam); ret = symFindByName(sysSymTbl,temp,&psub->sadr,&sub_type); - if ((ret < 0) || ((sub_type & N_TEXT) == 0)){ - psub->stat = BAD_SUB_ALARM; - psub->sevr = MAJOR; - psub->achn = 1; - monitor_sub(psub); - return(-1); + if ((ret !=OK) || ((sub_type & N_TEXT) == 0)){ + recGblRecordError(S_db_BadSub,psub,"recSub(init_record)"); + return(S_db_BadSub); } /* invoke the initialization subroutine */ - (long)psubroutine = psub->sadr; - if (psubroutine(psub,sub_callback, - &psub->a,&psub->b,&psub->c,&psub->d,&psub->e,&psub->f, - &psub->val) < 0){ - if (psub->brsv != NO_ALARM){ - psub->stat = RETURN_ALARM; - psub->sevr = psub->brsv; - psub->achn = 1; - monitor_sub(psub); - return(-1); - } - } + psubroutine = (FUNCPTR)(psub->sadr); + status = psubroutine(psub); + if(!status) return(status); /* convert the subroutine name to an address and type */ /* convert the initialization subroutine name */ @@ -177,15 +168,8 @@ static long init_record(psub) strcat(temp,psub->snam); ret = symFindByName(sysSymTbl,temp,&psub->sadr,&sub_type); if ((ret < 0) || ((sub_type & N_TEXT) == 0)){ - psub->styp = sub_type; - psub->stat = BAD_SUB_ALARM; - psub->sevr = MAJOR; - psub->achn = 1; - monitor_sub(psub); - return(-1); - }else if (psub->stat != NO_ALARM){ - psub->sevr = psub->stat = NO_ALARM; - psub->achn = 1; + recGblRecordError(S_db_BadSub,psub,"recSub(init_record)"); + return(S_db_BadSub); } psub->styp = sub_type; return(0); @@ -198,7 +182,7 @@ static long get_precision(paddr,precision) struct subRecord *psub=(struct subRecord *)paddr->precord; *precision = psub->prec; - return(0L); + return(0); } static long get_value(psub,pvdes) @@ -210,7 +194,7 @@ static long get_value(psub,pvdes) (float *)(pvdes->pvalue) = &psub->val; return(0); } - + static long get_units(paddr,units) struct dbAddr *paddr; char *units; @@ -218,7 +202,7 @@ static long get_units(paddr,units) struct subRecord *psub=(struct subRecord *)paddr->precord; strncpy(units,psub->egu,sizeof(psub->egu)); - return(0L); + return(0); } static long get_graphic_double(paddr,pgd) @@ -233,7 +217,7 @@ static long get_graphic_double(paddr,pgd) pgd->upper_warning_limit = psub->high; pgd->lower_warning_limit = psub->low; pgd->lower_alarm_limit = psub->lolo; - return(0L); + return(0); } static long get_control_double(paddr,pcd) @@ -244,538 +228,189 @@ static long get_control_double(paddr,pcd) pcd->upper_ctrl_limit = psub->hopr; pcd->lower_ctrl_limit = psub->lopr; - return(0L); + return(0); } static long process(paddr) struct dbAddr *paddr; { - struct subRecord *psub=(struct subRecord *)(paddr->precord); - struct subdset *pdset = (struct subdset *)(psub->dset); + struct subRecord *psub=(struct subRecord *)(paddr->precord); long status; - psub->achn = 0; - /* read inputs */ - if (fetch_values(psub) < 0){ - if (psub->stat != READ_ALARM){ - psub->stat = READ_ALARM; - psub->sevr = MAJOR_ALARM; - psub->achn = 1; - monitor_sub(psub); - } - psub->pact = 0; - return(0); - }else{ - if (psub->stat == READ_ALARM){ - psub->stat = NO_ALARM; - psub->sevr = NO_ALARM; - psub->achn = 1; - } + if(!psub->pact){ + psub->pact = TRUE; + fetch_values(psub); + psub->pact = FALSE; } - - /* perform subulation */ - if (do_sub(psub) < 0){ - if (psub->stat != CALC_ALARM){ - psub->stat = CALC_ALARM; - psub->sevr = MAJOR_ALARM; - psub->achn = 1; - monitor_sub(psub); - } - psub->pact = 0; - return; - }else{ - if (psub->stat == CALC_ALARM){ - psub->stat = NO_ALARM; - psub->sevr = NO_ALARM; - psub->achn = 1; - } - } - - /* check for alarms */ - alarm(psub); - - - /* check event list */ - if(!psub->disa) status = monitor(psub); - - /* process the forward scan link record */ - if (psub->flnk.type==DB_LINK) dbScanPassive(&psub->flnk.value); - - psub->pact=FALSE; - return(status); + status = do_sub(psub); + psub->pact = TRUE; + if(status==1) return(0); + /* check for alarms */ + alarm(psub); + /* check event list */ + monitor(psub); + /* process the forward scan link record */ + if (psub->flnk.type==DB_LINK) dbScanPassive(&psub->flnk.value.db_link.pdbAddr); + psub->pact = FALSE; + return(0); } -/* - * FETCH_VALUES - * - * fetch the values for the variables in the subulation - */ -static fetch_values(psub) -struct subRecord *psub; -{ - short status; - - /* note - currently not using alarm status */ - status = 0; - status |= get_sub_inp(&psub->inpa,&psub->a); - status |= get_sub_inp(&psub->inpb,&psub->b); - status |= get_sub_inp(&psub->inpc,&psub->c); - status |= get_sub_inp(&psub->inpd,&psub->d); - status |= get_sub_inp(&psub->inpe,&psub->e); - status |= get_sub_inp(&psub->inpf,&psub->f); - return(status); -} - -/* - * GET_CALC_INPUT - * - * return an input value - */ -static get_sub_inp(plink,pvalue) -struct link *plink; /* structure of the link field */ -float *pvalue; -{ - float float_value; - - /* database link */ - if (plink->type == DB_LINK){ - if (dbGetLink(&plink->value.db_link,DBR_FLOAT,&float_value,1) < 0) - return(-1); - *pvalue = float_value; - - /* constant */ - }else if (plink->type == CONSTANT){ - ; - /* illegal link type */ - }else{ - return(-1); - } - return(0); - -} - -static long alarm(psub) +static void alarm(psub) struct subRecord *psub; { float ftemp; - /* if in alarm and difference is not > hysterisis don't bother */ - if (psub->stat != NO_ALARM){ - ftemp = psub->lalm - psub->val; - if(ftemp<0.0) ftemp = -ftemp; - if (ftemp < psub->hyst) return(0); - } + /* if difference is not > hysterisis don't bother */ + ftemp = psub->lalm - psub->val; + if(ftemp<0.0) ftemp = -ftemp; + if (ftemp < psub->hyst) return; - /* alarm condition hihi */ - if (psub->hhsv != NO_ALARM){ - if (psub->val > psub->hihi){ - psub->lalm = psub->val; - if (psub->stat != HIHI_ALARM){ - psub->stat = HIHI_ALARM; - psub->sevr = psub->hhsv; - psub->achn = 1; - } - return(0); - } - } + /* alarm condition hihi */ + if (psub->nsevhhsv){ + if (psub->val > psub->hihi){ + psub->lalm = psub->val; + psub->nsta = HIHI_ALARM; + psub->nsev = psub->hhsv; + return; + } + } - /* alarm condition lolo */ - if (psub->llsv != NO_ALARM){ - if (psub->val < psub->lolo){ - psub->lalm = psub->val; - if (psub->stat != LOLO_ALARM){ - psub->stat = LOLO_ALARM; - psub->sevr = psub->llsv; - psub->achn = 1; - } - return(0); - } - } + /* alarm condition lolo */ + if (psub->nsevllsv){ + if (psub->val < psub->lolo){ + psub->lalm = psub->val; + psub->nsta = LOLO_ALARM; + psub->nsev = psub->llsv; + return; + } + } - /* alarm condition high */ - if (psub->hsv != NO_ALARM){ - if (psub->val > psub->high){ - psub->lalm = psub->val; - if (psub->stat != HIGH_ALARM){ - psub->stat = HIGH_ALARM; - psub->sevr =psub->hsv; - psub->achn = 1; - } - return(0); - } - } - - /* alarm condition lolo */ - if (psub->lsv != NO_ALARM){ - if (psub->val < psub->low){ - psub->lalm = psub->val; - if (psub->stat != LOW_ALARM){ - psub->stat = LOW_ALARM; - psub->sevr = psub->lsv; - psub->achn = 1; - } - return(0); - } - } - - /* no alarm */ - if (psub->stat != NO_ALARM){ - psub->stat = NO_ALARM; - psub->sevr = NO_ALARM; - psub->achn = 1; - } - - return(0); + /* alarm condition high */ + if (psub->nsevhsv){ + if (psub->val > psub->high){ + psub->lalm = psub->val; + psub->nsta = HIGH_ALARM; + psub->nsev =psub->hsv; + return; + } + } + /* alarm condition lolo */ + if (psub->nsevlsv){ + if (psub->val < psub->low){ + psub->lalm = psub->val; + psub->nsta = LOW_ALARM; + psub->nsev = psub->lsv; + return; + } + } + return; } -static long monitor(psub) +static void monitor(psub) struct subRecord *psub; { unsigned short monitor_mask; float delta; + short stat,sevr,nsta,nsev; - /* anyone wsubting for an event on this record */ - if (psub->mlis.count == 0) return(0L); - - /* Flags which events to fire on the value field */ - monitor_mask = 0; - - /* alarm condition changed this scan */ - if (psub->achn){ - /* post events for alarm condition change and value change */ - monitor_mask = DBE_ALARM | DBE_VALUE | DBE_LOG; - - /* post stat and sevr fields */ - db_post_events(psub,&psub->stat,DBE_VALUE); - db_post_events(psub,&psub->sevr,DBE_VALUE); - - /* update last value monitored */ - psub->mlst = psub->val; - - /* check for value change */ - }else{ - delta = psub->mlst - psub->val; - if(delta<0.0) delta = -delta; - if (delta > psub->mdel) { - /* post events for value change */ - monitor_mask = DBE_VALUE; - - /* update last value monitored */ - psub->mlst = psub->val; - } - } - - /* check for archive change */ - delta = psub->alst - psub->val; - if(delta<0.0) delta = 0.0; - if (delta > psub->adel) { - /* post events on value field for archive change */ - monitor_mask |= DBE_LOG; - - /* update last archive value monitored */ - psub->alst = psub->val; - } - - /* send out monitors connected to the value field */ - if (monitor_mask){ - db_post_events(psub,&psub->val,monitor_mask); - } - return(0L); -} - -process_sub(psub) -register struct sub *psub; /* pointer to subroutine record */ -{ - psub->achn = 0; - - /* lock the record */ - if (psub->lock){ - if (psub->lcnt >= MAX_LOCK){ - psub->stat = SCAN_ALARM; - psub->sevr = MAJOR; - psub->achn = 1; - monitor_sub(psub); - }else{ - psub->lcnt++; - } - return; - } - psub->lcnt = 0; - psub->lock = 1; - - if (psub->init == 0){ - if (sub_init(psub) < 0){ - psub->lock = 0; - return; - } - } - - /* check for valid subroutine connection */ - if (psub->stat == BAD_SUB_ALARM){ - psub->lock = 0; - return; - } - - /* perform the subroutine call */ - do_sub(psub); - - /* do post processing for synchronous routines */ - if (psub->rtcb == FALSE){ - sub_callback(psub); - } - /* unlock of record is done in sub_callback either directly (above) */ - /* or asynchronously through the callback mechanism */ -} - -/* - * SUB_CALLBACK - * - * subroutine values returned handling - - * either called immediately for fast routines or asynchronously for slow - * routines (i.e. GPIB interfaces that require a wait) - */ -sub_callback(psub) -register struct sub *psub; /* pointer to subroutine record */ -{ - /* check for alarms */ - if ((psub->stat != READ_ALARM) && (psub->stat != RETURN_ALARM) - && (psub->stat != BAD_SUB_ALARM)) - alarm_sub(psub); - - /* check for monitors */ - monitor_sub(psub); - - /* process the forward scan link record */ - if (psub->flnk.type == DB_LINK) - db_scan(&psub->flnk.value); - - /* unlock the record */ - psub->lock = 0; -} - -/* - * DO_SUB - * - * invoke the subroutine - */ -static do_sub(psub) -register struct sub *psub; /* pointer to subroutine record */ -{ - register short status; - register FUNCPTR psubroutine; - - /* get the subroutine arguments */ - status = 0; - if (psub->inpa.type == DB_LINK){ - if (db_fetch(&psub->inpa.value.db_link,&psub->a) < 0) - status |= -1; - } - if (psub->inpb.type == DB_LINK){ - if (db_fetch(&psub->inpb.value.db_link,&psub->b) < 0) - status |= -1; - } - if (psub->inpc.type == DB_LINK){ - if (db_fetch(&psub->inpc.value.db_link,&psub->c) < 0) - status |= -1; - } - if (psub->inpd.type == DB_LINK){ - if (db_fetch(&psub->inpd.value.db_link,&psub->d) < 0) - status |= -1; - } - if (psub->inpe.type == DB_LINK){ - if (db_fetch(&psub->inpe.value.db_link,&psub->e) < 0) - status |= -1; - } - if (psub->inpf.type == DB_LINK){ - if (db_fetch(&psub->inpf.value.db_link,&psub->f) < 0) - status |= -1; - } - if (status != 0){ - psub->stat = READ_ALARM; - psub->sevr = MAJOR; - psub->achn = 1; - return; - } - - /* call the subroutine */ - (long)psubroutine = psub->sadr; - if (psubroutine(psub,sub_callback, - &psub->a,&psub->b,&psub->c,&psub->d,&psub->e,&psub->f, - &psub->val) < 0){ - if (psub->brsv != NO_ALARM){ - psub->stat = RETURN_ALARM; - psub->sevr = psub->brsv; - psub->achn = 1; - return; - } - }else{ - if (psub->brsv != NO_ALARM){ - psub->stat = NO_ALARM; - psub->sevr = NO_ALARM; - psub->achn = 1; - return; - } - } - return; -} - -/* - * ALARM_SUB - * - * check the alarm condition - */ -static alarm_sub(psub) -register struct sub *psub; -{ - register float ftemp; - - /* if in alarm and difference is not > hysterisis don't bother */ - if (psub->stat != NO_ALARM){ - ftemp = psub->lalm - psub->val; - if ( (ftemp < psub->hyst) && (ftemp > -psub->hyst)) - return; - } - - /* alarm condition hihi */ - if (psub->hhsv != NO_ALARM){ - if (psub->val > psub->hihi){ - if (psub->stat != HIHI_ALARM){ - psub->stat = HIHI_ALARM; - psub->sevr = psub->hhsv; - psub->lalm = psub->val; - psub->achn = 1; - } - return; - } - } - - /* alarm condition lolo */ - if (psub->llsv != NO_ALARM){ - if (psub->val < psub->lolo){ - if (psub->stat != LOLO_ALARM){ - psub->stat = LOLO_ALARM; - psub->sevr = psub->llsv; - psub->lalm = psub->val; - psub->achn = 1; - } - return; - } - } - - /* alarm condition high */ - if (psub->hsv != NO_ALARM){ - if (psub->val > psub->high){ - if (psub->stat != HIGH_ALARM){ - psub->stat = HIGH_ALARM; - psub->sevr = psub->hsv; - psub->lalm = psub->val; - psub->achn = 1; - } - return; - } - } - - /* alarm condition low */ - if (psub->lsv != NO_ALARM){ - if (psub->val < psub->low){ - if (psub->stat != LOW_ALARM){ - psub->stat = LOW_ALARM; - psub->sevr = psub->lsv; - psub->lalm = psub->val; - psub->achn = 1; - } - return; - } - } - - /* no alarm */ - if (psub->stat != NO_ALARM){ - psub->stat = NO_ALARM; - psub->sevr = NO_ALARM; - psub->achn = 1; - } - - return; -} - -/* - * MONITOR_SUB - * - * process subroutine record monitors - */ -static monitor_sub(psub) -register struct sub *psub; /* pointer to the subroutine record */ -{ - register unsigned short monitor_mask; - register float delta; + /* get previous stat and sevr and new stat and sevr*/ + stat=psub->stat; + sevr=psub->sevr; + nsta=psub->nsta; + nsev=psub->nsev; + /*set current stat and sevr*/ + psub->stat = nsta; + psub->sevr = nsev; + psub->nsta = 0; + psub->nsev = 0; /* anyone waiting for an event on this record */ - if (psub->mqct == 0) return; - - /* check monitors for each of the argument fields */ - if (psub->la != psub->a){ - db_post_events(psub,&psub->a,DBE_VALUE); - psub->la = psub->a; - } - if (psub->lb != psub->b){ - db_post_events(psub,&psub->b,DBE_VALUE); - psub->la = psub->b; - } - if (psub->lc != psub->c){ - db_post_events(psub,&psub->c,DBE_VALUE); - psub->lc = psub->c; - } - if (psub->ld != psub->d){ - db_post_events(psub,&psub->d,DBE_VALUE); - psub->ld = psub->d; - } - if (psub->le != psub->e){ - db_post_events(psub,&psub->e,DBE_VALUE); - psub->le = psub->e; - } - if (psub->lf != psub->f){ - db_post_events(psub,&psub->f,DBE_VALUE); - psub->lf = psub->f; - } + if (psub->mlis.count == 0) return; /* Flags which events to fire on the value field */ monitor_mask = 0; /* alarm condition changed this scan */ - if (psub->achn != 0){ - /* post events for alarm condition change and value change */ - monitor_mask = DBE_ALARM | DBE_VALUE; - - /* post stat and sevr fields */ + if (stat!=nsta || sevr!=nsev) { + /* post events for alarm condition change*/ + monitor_mask = DBE_ALARM; + /* post stat and nsev fields */ db_post_events(psub,&psub->stat,DBE_VALUE); db_post_events(psub,&psub->sevr,DBE_VALUE); - + } + /* check for value change */ + delta = psub->mlst - psub->val; + if(delta<0.0) delta = -delta; + if (delta > psub->mdel) { + /* post events for value change */ + monitor_mask |= DBE_VALUE; /* update last value monitored */ psub->mlst = psub->val; - - /* check for value change */ - }else{ - delta = psub->mlst - psub->val; - if ((delta > psub->mdel) || (delta < -psub->mdel)){ - /* post events for value change */ - monitor_mask = DBE_VALUE; - - /* update last value monitored */ - psub->mlst = psub->val; - } } - /* check for archive change */ delta = psub->alst - psub->val; - if ((delta > psub->adel) || (delta < -psub->adel)){ + if(delta<0.0) delta = 0.0; + if (delta > psub->adel) { /* post events on value field for archive change */ monitor_mask |= DBE_LOG; - /* update last archive value monitored */ psub->alst = psub->val; } - /* send out monitors connected to the value field */ - if (monitor_mask) + if (monitor_mask){ db_post_events(psub,&psub->val,monitor_mask); + } + return; +} + +static void fetch_values(psub) +struct subRecord *psub; +{ + struct link *plink; /* structure of the link field */ + float *pvalue; + long options,nRequest; + int i; + + for(i=0, plink=&psub->inpa, pvalue=&psub->a; i<6; i++, plink++, pvalue++) { + if(plink->type!=DB_LINK) continue; + options=0; + nRequest=1; + (void)dbGetLink(&plink->value.db_link,psub,DBR_FLOAT, + pvalue,&options,&nRequest); + } + return; +} + +static void callback(psub) +struct subRecord *psub; /* pointer to subroutine record */ +{ + dbScanLock(psub); + (void)process(psub); + dbScanUnlock(psub); +} + +static long do_sub(psub) +struct subRecord *psub; /* pointer to subroutine record */ +{ + short status; + FUNCPTR psubroutine; + + + /* call the subroutine */ + psubroutine = (FUNCPTR)(psub->sadr); + if(psubroutine==NULL) { + if(psub->nsevnsta = BAD_SUB_ALARM; + psub->nsev = MAJOR_ALARM; + } + return(0); + } + status = psubroutine(psub,callback); + if(status < 0){ + if (psub->nsevbrsv){ + psub->nsta = SOFT_ALARM; + psub->nsev = psub->brsv; + } + } + return(status); } diff --git a/src/rec/recTimer.c b/src/rec/recTimer.c index 8accf19e2..ae34c2472 100644 --- a/src/rec/recTimer.c +++ b/src/rec/recTimer.c @@ -1,4 +1,3 @@ - /* recTimer.c */ /* share/src/rec $Id$ */ @@ -48,7 +47,6 @@ #include #include -#include #include #include #include @@ -56,7 +54,6 @@ #include #include #include -#include #include /* Create RSET - Record Support Entry Table*/ @@ -64,16 +61,16 @@ long report(); #define initialize NULL long init_record(); long process(); -#define special(); -#define get_precision(); +#define special NULL +#define get_precision NULL long get_value(); #define cvt_dbaddr NULL #define get_array_info NULL #define put_array_info NULL #define get_enum_str NULL -#define get_units(); -#define get_graphic_double(); -#define get_control_double(); +#define get_units NULL +#define get_graphic_double NULL +#define get_control_double NULL #define get_enum_strs NULL struct rset timerRSET={ @@ -95,9 +92,16 @@ struct rset timerRSET={ get_enum_strs }; /* because the driver does all the work just declare device support here*/ -struct dset devMizar8310={4,NULL,NULL,NULL,NULL}; -struct dset devDg535={4,NULL,NULL,NULL,NULL}; -struct dset devVxiAt5Time={4,NULL,NULL,NULL,NULL}; +struct dset devTmMizar8310={4,NULL,NULL,NULL,NULL}; +struct dset devTmDg535={4,NULL,NULL,NULL,NULL}; +struct dset devTmVxiAt5={4,NULL,NULL,NULL,NULL}; + +extern int post_event(); + +void monitor(); +void read_timer(); +void convert_timer(); +void write_timer(); static long report(fp,paddr) FILE *fp; @@ -107,37 +111,18 @@ static long report(fp,paddr) if(recGblReportDbCommon(fp,paddr)) return(-1); if(fprintf(fp,"VAL %-12.4G\n",ptimer->val)) return(-1); - if(recGblReportLink(fp,"INP ",&(ptimer->inp))) return(-1); - if(fprintf(fp,"PREC %d\n",ptimer->prec)) return(-1); - if(recGblReportCvtChoice(fp,"LINR",ptimer->linr)) return(-1); - if(fprintf(fp,"HOPR %-12.4G LOPR %-12.4G\n", - ptimer->hopr,ptimer->lopr)) return(-1); - if(recGblReportLink(fp,"FLNK",&(ptimer->flnk))) return(-1); - if(fprintf(fp,"HIHI %-12.4G HIGH %-12.4G LOW %-12.4G LOLO %-12.4G\n", - ptimer->hihi,ptimer->high,ptimer->low,ptimer->lolo)) return(-1); - if(recGblReportGblChoice(fp,ptimer,"HHSV",ptimer->hhsv)) return(-1); - if(recGblReportGblChoice(fp,ptimer,"HSV ",ptimer->hsv)) return(-1); - if(recGblReportGblChoice(fp,ptimer,"LSV ",ptimer->lsv)) return(-1); - if(recGblReportGblChoice(fp,ptimer,"LLSV",ptimer->llsv)) return(-1); - if(fprintf(fp,"HYST %-12.4G ADEL %-12.4G MDEL %-12.4G ESLO %-12.4G\n", - ptimer->hyst,ptimer->adel,ptimer->mdel,ptimer->eslo)) return(-1); - if(fprintf(fp,"RVAL 0x%-8X ACHN %d\n", - ptimer->rval,ptimer->achn)) return(-1); - if(fprintf(fp,"LALM %-12.4G ALST %-12.4G MLST %-12.4G\n", - ptimer->lalm,ptimer->alst,ptimer->mlst)) return(-1); return(0); } static long init_record(ptimer) struct timerRecord *ptimer; { - long status; /* read to maintain time pulses over a restart */ read_timer(ptimer); return(0); } - + static long get_value(ptimer,pvdes) struct timerRecord *ptimer; struct valueDes *pvdes; @@ -148,39 +133,63 @@ static long get_value(ptimer,pvdes) return(0); } -extern int post_event(); - static long process(paddr) struct dbAddr *paddr; { struct timerRecord *ptimer=(struct timerRecord *)(paddr->precord); - long status; ptimer->pact=TRUE; - ptimer->achn = 0; /* init the alarm change flag */ /* write the new value */ write_timer(ptimer); - /* need to post events for an alarm condition change */ - if ((ptimer->achn) && (ptimer->mlis.count!=0)) - db_post_events(ptimer,&ptimer->val,DBE_ALARM); + /* check event list */ + monitor(ptimer); + /* process the forward scan link record */ + if (ptimer->flnk.type==DB_LINK) dbScanPassive(&ptimer->flnk.value.db_link.pdbAddr); - if (ptimer->mlis.count!=0){ - db_post_events(ptimer,&ptimer->val,DBE_VALUE); - db_post_events(ptimer,&ptimer->t1wd,DBE_VALUE); - db_post_events(ptimer,&ptimer->t1ld,DBE_VALUE); - db_post_events(ptimer,&ptimer->t1td,DBE_VALUE); - } + ptimer->pact=FALSE; + return(0); +} - /* process the forward scan link record */ - if (ptimer->flnk.type == DB_LINK) - dbScanPassive(&ptimer->flnk.value); +static void monitor(ptimer) +struct timerRecord *ptimer; +{ + unsigned short monitor_mask; + short stat,sevr,nsta,nsev; - /* unlock the record */ - ptimer->lock = 0; - ptimer->pact=FALSE; - return(0); + /* get previous stat and sevr and new stat and sevr*/ + stat=ptimer->stat; + sevr=ptimer->sevr; + nsta=ptimer->nsta; + nsev=ptimer->nsev; + /*set current stat and sevr*/ + ptimer->stat = nsta; + ptimer->sevr = nsev; + ptimer->nsta = 0; + ptimer->nsev = 0; + + /* anyone waiting for an event on this record */ + if (ptimer->mlis.count == 0) return; + + /* Flags which events to fire on the value field */ + monitor_mask = 0; + + /* alarm condition changed this scan */ + if (stat!=nsta || sevr!=nsev){ + /* post events for alarm condition change*/ + monitor_mask = DBE_ALARM; + /* post stat and sevr fields */ + db_post_events(ptimer,&ptimer->stat,DBE_VALUE); + db_post_events(ptimer,&ptimer->sevr,DBE_VALUE); + } + + monitor_mask |= (DBE_VALUE | DBE_LOG); + db_post_events(ptimer,&ptimer->val,monitor_mask); + db_post_events(ptimer,&ptimer->t1wd,monitor_mask); + db_post_events(ptimer,&ptimer->t1ld,monitor_mask); + db_post_events(ptimer,&ptimer->t1td,monitor_mask); + return; } /* @@ -192,8 +201,8 @@ static double constants[] = {1000,1000000,1000000000,1000000000000}; * CONVERT_TIMER * */ -static convert_timer(ptimer) -register struct timer *ptimer; +static void convert_timer(ptimer) +struct timerRecord *ptimer; { double constant; @@ -246,32 +255,27 @@ register struct timer *ptimer; * * convert the value and write it */ -static write_timer(ptimer) -register struct timer *ptimer; +static void write_timer(ptimer) +struct timerRecord *ptimer; { - register struct vmeio *pvmeio; - register double *pdelay; - register short count; - register short i; + struct vmeio *pvmeio; + long status,options,nRequest; /* get the delay from trigger source */ - if (ptimer->torg.type == DB_LINK){ - if (db_fetch(&ptimer->torg.value,&ptimer->trdl) < 0){ - if (ptimer->stat != READ_ALARM){ - ptimer->stat = READ_ALARM; - ptimer->sevr = MAJOR; - ptimer->achn = 1; - } - return(-1); - }else if (ptimer->stat == READ_ALARM){ - ptimer->stat = NO_ALARM; - ptimer->sevr = NO_ALARM; - ptimer->achn = 1; - } + if (ptimer->torg.type == DB_LINK) { + options=0; + nRequest=1; + status = dbGetLink(&(ptimer->torg.value.db_link),ptimer,DBR_FLOAT, + &(ptimer->trdl),&options,&nRequest); + if(status!=0) return; + } + if (ptimer->out.type != VME_IO) { + if(ptimer->nsevnsta = WRITE_ALARM; + ptimer->nsev = MAJOR_ALARM; + } + return; } - - if (ptimer->out.type != VME_IO) return(-1); - pvmeio = (struct vmeio *)(&ptimer->out.value); /* convert the value */ @@ -280,26 +284,20 @@ register struct timer *ptimer; /* put the value to the ao driver */ if (time_driver((int)pvmeio->card, /* card number */ (int)pvmeio->signal, /* signal number */ - (int)ptimer->type, /* card type */ + (int)ptimer->dtyp, /* card type */ (int)ptimer->tsrc, /* trigger source */ (int)ptimer->ptst, /* pre-trigger state */ &ptimer->t1dl, /* delay/width array */ 1, /* number of pulses */ ((ptimer->tevt == 0)?0:post_event), /* addr of event post routine */ (int)ptimer->tevt) /* event to post on trigger */ - != NO_ALARM){ - if (ptimer->stat != WRITE_ALARM){ - ptimer->stat = WRITE_ALARM; - ptimer->sevr = MAJOR; - ptimer->achn = 1; + != 0){ + if (ptimer->nsevnsta = WRITE_ALARM; + ptimer->nsev = MAJOR_ALARM; } - return(-1); - }else if (ptimer->stat == WRITE_ALARM){ - ptimer->stat = NO_ALARM; - ptimer->sevr = NO_ALARM; - ptimer->achn = 1; } - return(0); + return; } /* @@ -307,10 +305,10 @@ register struct timer *ptimer; * * read the current timer pulses and convert them to engineering units */ -static read_timer(ptimer) -register struct timer *ptimer; +static void read_timer(ptimer) +struct timerRecord *ptimer; { - register struct vmeio *pvmeio; + struct vmeio *pvmeio; int source; int ptst; int no_pulses; @@ -318,17 +316,19 @@ register struct timer *ptimer; double constant; /* initiate the write */ - if (ptimer->out.type != VME_IO) return(-1); + if (ptimer->out.type != VME_IO) { + recGblRecordError(S_dev_badOutType,ptimer,"read_timer"); + return; + } /* only supports a one channel VME timer module !!!! */ - pvmeio = (struct vmeio *)(&ptimer->out.value); /* put the value to the ao driver */ if (time_driver_read((int)pvmeio->card, /* card number */ (int)pvmeio->signal, /* signal number */ - (int)ptimer->type, /* card type */ + (int)ptimer->dtyp, /* card type */ &source, /* trigger source */ &ptst, /* pre-trigger state */ &time_pulse[0], /* delay/width */ @@ -347,5 +347,5 @@ register struct timer *ptimer; ptimer->opw1 = time_pulse[1] * constant; /* pulse width */ ptimer->ptst = ptst; /* pre-trigger state */ ptimer->tsrc = source; /* clock source */ - return(0); + return; } diff --git a/src/rec/recWaveform.c b/src/rec/recWaveform.c index ac3b1da1d..a002affab 100644 --- a/src/rec/recWaveform.c +++ b/src/rec/recWaveform.c @@ -1,6 +1,6 @@ /* recWaveform.c - Record Support Routines for Waveform records /* share/src/rec $Id$ */ - * +/* * Author: Bob Dalesio * Date: 7-14-89 @@ -51,10 +51,8 @@ #include #include #include -#include #include -#include #include #include #include @@ -62,7 +60,6 @@ #include #include #include -#include #include /* Create RSET - Record Support Entry Table*/ @@ -99,70 +96,88 @@ struct rset waveformRSET={ get_graphic_double, get_control_double, get_enum_strs }; -/* because the driver does all the work just declare device support here*/ -struct dset devWaveformSoft={4,NULL,NULL,NULL,NULL}; -struct dset devXycom566SingleChan={4,NULL,NULL,NULL,NULL}; -struct dset devLecroy8837={4,NULL,NULL,NULL,NULL}; -struct dset devJoergerVtr1={4,NULL,NULL,NULL,NULL}; +struct wfdset { /* waveform dset */ + long number; + DEVSUPFUN report; + DEVSUPFUN init; + DEVSUPFUN init_record; /*returns: (-1,0)=>(failure,success)*/ + DEVSUPFUN get_ioint_info; + DEVSUPFUN read_wf;/*(0,1)=> success and */ + /*(convert,don't continue)*/ +}; + +/*sizes of field types*/ +static int sizeofTypes[] = {0,1,1,2,2,4,4,4,8,2}; +void monitor(); static long report(fp,paddr) FILE *fp; struct dbAddr *paddr; { - struct waveformRecord *pwaveform=(struct waveformRecord*)(paddr->precord); + struct waveformRecord *pwf=(struct waveformRecord*)(paddr->precord); if(recGblReportDbCommon(fp,paddr)) return(-1); return(0); } -static long init_record(pwaveform) - struct waveformRecord *pwaveform; +static long init_record(pwf) + struct waveformRecord *pwf; { + struct wfdset *pdset; long status; /* This routine may get called twice. Once by cvt_dbaddr. Once by iocInit*/ - /* allocate bptr and sptr */ - if(pwaveform->bptr==NULL) { - if(pwaveform->nsam<=0) pwaveform->nsam=1; - pwaveform->bptr = (char *)malloc(pwaveform->nsam * pwaveform->selm); + if(pwf->bptr==NULL) { + if(pwf->nelm<=0) pwf->nelm=1; + if(pwf->ftvl<=0|| pwf->ftvl>DBF_ENUM) pwf->ftvl=2; + pwf->bptr = (char *)malloc(pwf->nelm * sizeofTypes[pwf->ftvl]); + pwf->nord = 0; + /* must have read_wf function defined */ + if( (pdset->number < 6) || (pdset->read_wf == NULL) ) { + recGblRecordError(S_dev_missingSup,pwf,"wf: init_record"); + return(S_dev_missingSup); + } + if( pdset->init_record ) { + if((status=(*pdset->init_record)(pwf,process))) return(status); + } } return(0); } - + static long get_precision(paddr,precision) struct dbAddr *paddr; long *precision; { - struct waveformRecord *pwaveform=(struct waveformRecord *)paddr->precord; + struct waveformRecord *pwf=(struct waveformRecord *)paddr->precord; - *precision = pwaveform->prec; - return(0L); -} - -static long get_value(pwaveform,pvdes) - struct waveformRecord *pwaveform; - struct valueDes *pvdes; -{ - pvdes->field_type = DBF_FLOAT; - pvdes->no_elements=pwaveform->nsam; - (float *)(pvdes->pvalue) = pwaveform->bptr; + *precision = pwf->prec; return(0); } +static long get_value(pwf,pvdes) + struct waveformRecord *pwf; + struct valueDes *pvdes; +{ + + pvdes->no_elements=pwf->nord; + pvdes->pvalue = pwf->bptr; + pvdes->field_type = pwf->ftvl; + return(0); +} + static long cvt_dbaddr(paddr) struct dbAddr *paddr; { - struct waveformRecord *pwaveform=(struct waveformRecord *)paddr->precord; + struct waveformRecord *pwf=(struct waveformRecord *)paddr->precord; /* This may get called before init_record. If so just call it*/ - if(pwaveform->bptr==NULL) init_record(paddr); - - paddr->pfield = (caddr_t)(pwaveform->bptr); - paddr->no_elements = pwaveform->nsam; - paddr->field_type = DBF_FLOAT; - paddr->field_size = sizeof(float); - paddr->dbr_field_type = DBF_FLOAT; + if(pwf->bptr==NULL) init_record(pwf); + paddr->pfield = (caddr_t)(pwf->bptr); + paddr->no_elements = pwf->nelm; + paddr->field_type = pwf->ftvl; + paddr->field_size = sizeofTypes[pwf->ftvl]; + paddr->dbr_field_type = pwf->ftvl; return(0); } @@ -171,289 +186,118 @@ static long get_array_info(paddr,no_elements,offset) long *no_elements; long *offset; { - struct waveformRecord *pwaveform=(struct waveformRecord *)paddr->precord; + struct waveformRecord *pwf=(struct waveformRecord *)paddr->precord; - *no_elements = pwaveform->nuse; - *offset = inx+1; + *no_elements = pwf->nord; + *offset = 0; return(0); } static long put_array_info(paddr,nNew) struct dbAddr *paddr; long nNew; - long offset; { - struct waveformRecord *pwaveform=(struct waveformRecord *)paddr->precord; + struct waveformRecord *pwf=(struct waveformRecord *)paddr->precord; - pwaveform->inx = (pwaveform->inx + nNew) % (pwaveform->nsam); - pwaveform->nuse = (pwaveform->nuse + nNew); - if(pwaveform->nuse > pwaveform->nsam) pwaveform->nuse = pwaveform->nsam; + pwf->nord = (pwf->nord + nNew); + if(pwf->nord > pwf->nelm) pwf->nord = pwf->nelm; return(0); } - - + static long get_units(paddr,units) struct dbAddr *paddr; char *units; { - struct waveformRecord *pwaveform=(struct waveformRecord *)paddr->precord; + struct waveformRecord *pwf=(struct waveformRecord *)paddr->precord; - strncpy(units,pwaveform->egu,sizeof(pwaveform->egu)); - return(0L); + strncpy(units,pwf->egu,sizeof(pwf->egu)); + return(0); } static long get_graphic_double(paddr,pgd) struct dbAddr *paddr; struct dbr_grDouble *pgd; { - struct waveformRecord *pwaveform=(struct waveformRecord *)paddr->precord; + struct waveformRecord *pwf=(struct waveformRecord *)paddr->precord; - pgd->upper_disp_limit = pwaveform->hopr; - pgd->lower_disp_limit = pwaveform->lopr; + pgd->upper_disp_limit = pwf->hopr; + pgd->lower_disp_limit = pwf->lopr; pgd->upper_alarm_limit = 0.0; pgd->upper_warning_limit = 0.0; pgd->lower_warning_limit = 0.0; pgd->lower_alarm_limit = 0.0; - return(0L); + return(0); } static long get_control_double(paddr,pcd) struct dbAddr *paddr; struct dbr_ctrlDouble *pcd; { - struct waveformRecord *pwaveform=(struct waveformRecord *)paddr->precord; + struct waveformRecord *pwf=(struct waveformRecord *)paddr->precord; - pgd->upper_disp_limit = pwaveform->hopr; - pgd->lower_disp_limit = pwaveform->lopr; - return(0L); + pcd->upper_ctrl_limit = pwf->hopr; + pcd->lower_ctrl_limit = pwf->lopr; + return(0); } static long process(paddr) struct dbAddr *paddr; { - struct waveformRecord *pwaveform=(struct waveformRecord *)(paddr->precord); - struct waveformdset *pdset = (struct waveformdset *)(pwaveform->dset); + struct waveformRecord *pwf=(struct waveformRecord *)(paddr->precord); + struct wfdset *pdset = (struct wfdset *)(pwf->dset); long status; - pwaveform->achn = 0; - /* read inputs */ - if (do_waveformion(pwaveform) < 0){ - if (pwaveform->stat != READ_ALARM){ - pwaveform->stat = READ_ALARM; - pwaveform->sevr = MAJOR_ALARM; - pwaveform->achn = 1; - monitor_waveform(pwaveform); - } - pwaveform->pact = 0; - return(0); - }else{ - if (pwaveform->stat == READ_ALARM){ - pwaveform->stat = NO_ALARM; - pwaveform->sevr = NO_ALARM; - pwaveform->achn = 1; - } - } + if( (pdset==NULL) || (pdset->read_wf==NULL) ) { + pwf->pact=TRUE; + recGblRecordError(S_dev_missingSup,pwf,"read_wf"); + return(S_dev_missingSup); + } + /*pact must not be set true until read_wf completes*/ + status=(*pdset->read_wf)(pwf); /* read the new value */ + pwf->pact = TRUE; + /* status is one if an asynchronous record is being processed*/ + if(status==1) return(0); + monitor(pwf); + /* process the forward scan link record */ + if (pwf->flnk.type==DB_LINK) dbScanPassive(&pwf->flnk.value.db_link.pdbAddr); - /* check event list */ - if(!pwaveform->disa) status = monitor(pwaveform); - - /* process the forward scan link record */ - if (pwaveform->flnk.type==DB_LINK) dbScanPassive(&pwaveform->flnk.value); - - pwaveform->pact=FALSE; - return(status); + pwf->pact=FALSE; + return(0); } -static long monitor(pwaveform) - struct waveformRecord *pwaveform; +static void monitor(pwf) + struct waveformRecord *pwf; { unsigned short monitor_mask; - float delta; + short stat,sevr,nsta,nsev; - /* anyone wwaveformting for an event on this record */ - if (pwaveform->mlis.count == 0) return(0L); + /* get previous stat and sevr and new stat and sevr*/ + stat=pwf->stat; + sevr=pwf->sevr; + nsta=pwf->nsta; + nsev=pwf->nsev; + /*set current stat and sevr*/ + pwf->stat = nsta; + pwf->sevr = nsev; + pwf->nsta = 0; + pwf->nsev = 0; - /* Flags which events to fire on the value field */ - monitor_mask = 0; + /* anyone waiting for an event on this record */ + if(pwf->mlis.count == 0) return; - /* alarm condition changed this scan */ - if (pwaveform->achn){ - /* post events for alarm condition change and value change */ - monitor_mask = DBE_ALARM; + /* Flags which events to fire on the value field */ + monitor_mask = 0; - /* post stat and sevr fields */ - db_post_events(pwaveform,&pwaveform->stat,DBE_VALUE); - db_post_events(pwaveform,&pwaveform->sevr,DBE_VALUE); - - /* update last value monitored */ - pwaveform->mlst = pwaveform->val; - } + /* alarm condition changed this scan */ + if (stat!=nsta || sevr!=nsev) { + /* post events for alarm condition change*/ + monitor_mask = DBE_ALARM; + /* post stat and nsev fields */ + db_post_events(pwf,&pwf->stat,DBE_VALUE); + db_post_events(pwf,&pwf->sevr,DBE_VALUE); + } monitor_mask |= DBE_LOG|DBE_VALUE; - db_post_events(pwaveform,&pwaveform->val,monitor_mask); - return(0L); -} - - -/* - * WFCB_READ - * - * callback routine when the waveform is read - */ -static wfcb_read(pwf,no_read,pdata) -register struct waveform *pwf; -register int no_read; -register char *pdata; -{ - if (pwf->inp.type == VME_IO){ - pwf->bptr = pdata; /* mem addr of buffer */ - pwf->nord = no_read; /* number of values read */ - pwf->busy = 0; - - /* post events on value, busy and number read */ - if (pwf->mqct != 0){ - db_post_events(pwf,&pwf->busy,DBE_VALUE); - db_post_events(pwf,&pwf->nord,DBE_VALUE); - db_post_events(pwf,&pwf->val,DBE_VALUE|DBE_LOG); - } - } - - /* process the forward scan link record */ - if (pwf->flnk.type == DB_LINK) - db_scan(&pwf->flnk.value); - - /* determine if the waveform is to be re-armed */ - if (pwf->rarm){ - arm_wf(pwf); - pwf->rarm = 0; - if (pwf->mqct) - db_post_events(pwf,&pwf->rarm,DBE_VALUE); - } - - /* record is only unlocked when the waveform is read */ - /* unlock the record */ - pwf->lock = 0; - -} - -/* - * PROCESS_WAVEFORM - * - * process waveform record - */ -process_waveform(pwf) -register struct waveform *pwf; /* pointer to the analog input record */ -{ - pwf->achn = 0; /* flags alarm condition changed */ - - /* lock the record */ - if (pwf->lock){ - if (pwf->lcnt >= MAX_LOCK){ - pwf->stat = SCAN_ALARM; - pwf->sevr = MAJOR; - pwf->achn = 1; - }else{ - pwf->lcnt++; - } - return; - } - pwf->lcnt = 0; - pwf->lock = 1; - - /* initialize the record */ - if(pwf->init == 0){ - init_wf(pwf); - pwf->init = 1; - } - - /* arm the waveform */ - arm_wf(pwf); - - /* monitors on alarm condition */ - if (pwf->mqct != 0){ - if (pwf->achn){ - db_post_events(pwf,&pwf->val,DBE_ALARM); - db_post_events(pwf,&pwf->stat,DBE_VALUE); - db_post_events(pwf,&pwf->sevr,DBE_VALUE); - } - if (pwf->inp.type == CONSTANT){ - db_post_events(pwf,&pwf->val,DBE_VALUE); - } - } -} - -/* - * ARM_WF - * - * arm the waveform - */ -static arm_wf(pwf) -register struct waveform *pwf; -{ - short temp; - - switch(pwf->inp.type){ - case(VME_IO): - if (pwf->busy) return; /* already armed */ - - /* setup callback for data collection complete */ - if (wf_driver(pwf->type, /* card type */ - pwf->inp.value.vmeio.card, /* card number */ - wfcb_read, /* callback routine */ - pwf) < 0){ /* callback argument */ - if (pwf->stat != READ_ALARM){ - pwf->stat = READ_ALARM; - pwf->sevr = MAJOR; - pwf->achn = 1; - } - return(-1); - }else{ - pwf->busy = 1; - if (pwf->mqct != 0) - db_post_events(pwf,&pwf->busy,DBE_VALUE); - if (pwf->stat == READ_ALARM){ - pwf->sevr = pwf->stat = NO_ALARM; - pwf->achn = 1; - } - } - return(0); - - case(CAMAC_IO): - case(CONSTANT): - case(DB_LINK): - default: - return(-1); - } - -} - -/* - * INIT_WF - * - * initialize the waveform parameters - */ -static init_wf(pwf) -register struct waveform *pwf; -{ - short temp; - - /* initialize the monitor mutual exclusion semaphore */ - semInit(&pwf->msem[0]); - semGive(&pwf->msem[0]); /* initially available */ - - - switch(pwf->inp.type){ - case(VME_IO): - return(0); - - case(CONSTANT): - pwf->bptr = (char *)malloc(pwf->nelm * pwf->selm); - pwf->nord = pwf->nelm; - return(0); - - case(DB_LINK): - case(CAMAC_IO): - default: - return(-1); - } + if(monitor_mask) db_post_events(pwf,pwf->bptr,monitor_mask); + return; }