makerelease

This commit is contained in:
Marty Kraimer
1990-11-30 09:51:58 +00:00
parent e4771c2496
commit 2b6886385b
16 changed files with 2107 additions and 2756 deletions

View File

@ -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->nsev<pai->hhsv){
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->nsev<pai->llsv){
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->nsev<pai->hsv){
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->nsev<pai->lsv){
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((val<pbrkTable->rawLow) || (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;
}

View File

@ -1,4 +1,3 @@
/* recAo.c */
/* share/src/rec $Id$ */
@ -57,13 +56,13 @@
#include <lstLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <dbDefs.h>
#include <dbFldTypes.h>
#include <devSup.h>
#include <errMdef.h>
#include <link.h>
#include <special.h>
#include <recSup.h>
#include <aoRecord.h>
@ -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->nsev<pao->hhsv){
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->nsev<pao->llsv){
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->nsev<pao->hsv){
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->nsev<pao->lsv){
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;

View File

@ -1,4 +1,3 @@
/* recBi.c */
/* share/src/rec $Id$ */
@ -51,7 +50,6 @@
#include <strLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <dbDefs.h>
#include <dbFldTypes.h>
@ -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->nsev<pbi->zsv){
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->nsev<pbi->osv){
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->nsev<pbi->cosv) {
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;
}

View File

@ -1,4 +1,3 @@
/* recBo.c */
/* share/src/rec $Id$ */
@ -57,9 +56,9 @@
#include <stdioLib.h>
#include <lstLib.h>
#include <strLib.h>
#include <wdLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <dbDefs.h>
#include <dbFldTypes.h>
@ -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->nsev<pbo->zsv){
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->nsev<pbo->osv){
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->nsev<pbo->cosv) {
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;
}

View File

@ -1,4 +1,3 @@
/* recCalc.c */
/* share/src/rec $Id$ */
@ -64,11 +63,9 @@
#include <math.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <dbDefs.h>
#include <dbFldTypes.h>
#include <devSup.h>
#include <errMdef.h>
#include <link.h>
#include <recSup.h>
@ -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->nsev<MAJOR_ALARM) {
pcalc->nsta = CALC_ALARM;
pcalc->nsev = MAJOR_ALARM;
}
}
if(pcalc->hopr!=pcalc->lopr) {
if(pcalc->val>pcalc->hopr) pcalc->val = pcalc->hopr;
if(pcalc->val<pcalc->lopr) 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->nsev<pcalc->hhsv){
if (pcalc->val > pcalc->hihi){
pcalc->lalm = pcalc->val;
pcalc->nsta = HIHI_ALARM;
pcalc->nsev = pcalc->hhsv;
return;
}
}
/* alarm condition lolo */
if (pcalc->nsev<pcalc->llsv){
if (pcalc->val < pcalc->lolo){
pcalc->lalm = pcalc->val;
pcalc->nsta = LOLO_ALARM;
pcalc->nsev = pcalc->llsv;
return;
}
}
/* alarm condition high */
if (pcalc->nsev<pcalc->hsv){
if (pcalc->val > pcalc->high){
pcalc->lalm = pcalc->val;
pcalc->nsta = HIGH_ALARM;
pcalc->nsev =pcalc->hsv;
return;
}
}
/* alarm condition lolo */
if (pcalc->nsev<pcalc->lsv){
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;

View File

@ -1,4 +1,3 @@
/* recCompress.c */
/* share/src/rec $Id$ */
@ -57,15 +56,13 @@
#include <math.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <dbDefs.h>
#include <dbFldTypes.h>
#include <devSup.h>
#include <errMdef.h>
#include <link.h>
#include <recSup.h>
#include <special.h>
#include <recSup.h>
#include <compressRecord.h>
/* 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->nsev<MAJOR_ALARM) {
pcompress->nsta = 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<n; i++, psource++) {
*pdest=*psource;
offset++;
if(offset>=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_elements<n) return(1); /*dont do anything*/
/* determine number of samples to take */
if ((no_elements - *off) < (pcompress->nsam * 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)++ <nsam) {
pdest++;
} else {
pdest = pcompress->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)++ <nsam) {
pdest++;
} else {
pdest = pcompress->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)++ <nsam) {
pdest++;
} else {
pdest = pcompress->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)++ <nsam) {
pdest++;
} else {
pdest = pcompress->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; i<nuse; i++) *psum++ = 0;
}else{
for (i = 0; i < nnow; i++)
*psum++ += *psource++;
}
/* do we need to calculate the result */
inx++;
if(pcompress->n<=0)pcompress->n=1;
n = pcompress->n;
if(inx<n) return(1);
if(n>1) {
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);
}
}

View File

@ -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 <vxWorks.h>
@ -38,11 +43,9 @@
#include <lstLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <dbDefs.h>
#include <dbFldTypes.h>
#include <devSup.h>
#include <errMdef.h>
#include <link.h>
#include <recSup.h>
@ -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);
}

View File

@ -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 <vxWorks.h>
@ -54,7 +53,6 @@
#include <strLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <dbDefs.h>
#include <dbFldTypes.h>
@ -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->nsev<pmbbi->unsv){
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->nsev<severities[pmbbi->val]){
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->nsev<pmbbi->cosv){
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;
}

View File

@ -1,4 +1,3 @@
/* recMbbo.c */
/* share/src/rec $Id$ */
@ -57,7 +56,6 @@
#include <strLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <dbDefs.h>
#include <dbFldTypes.h>
@ -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->nsev<pmbbo->unsv){
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->nsev<severities[pmbbo->val]){
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->nsev<pmbbo->cosv){
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;
}

View File

@ -1,4 +1,3 @@
/* recPermissive.c */
/* share/src/rec $Id$ */
@ -37,16 +36,12 @@
#include <stdioLib.h>
#include <lstLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <dbDefs.h>
#include <dbFldTypes.h>
#include <devSup.h>
#include <errMdef.h>
#include <link.h>
#include <recSup.h>
#include <special.h>
#include <permissiveRecord.h>
/* 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);
}

View File

@ -1,4 +1,3 @@
/* recPid.c */
/* share/src/rec $Id$ */
@ -36,16 +35,16 @@
#include <types.h>
#include <stdioLib.h>
#include <lstLib.h>
/*since tickLib is not defined just define tickGet*/
unsigned long tickGet();
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <dbDefs.h>
#include <dbFldTypes.h>
#include <errMdef.h>
#include <link.h>
#include <recSup.h>
#include <special.h>
#include <pidRecord.h>
/* 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->nsev<ppid->hhsv){
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->nsev<ppid->llsv){
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->nsev<ppid->hsv){
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->nsev<ppid->lsv){
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->nsev<MAJOR_ALARM) {
ppid->nsta = 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->nsev<MAJOR_ALARM) {
ppid->nsta = 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->nsev<MAJOR_ALARM) {
ppid->stat = 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(ctp<ct) {
dt = (float)(ct-ctp);
}else { /* clock has overflowed */
dt = (unsigned long)(0xffffffff) - ctp;
dt = dt + ct + 1;
}
dt = dt/vxTicksPerSecond;
if(dt<ppid->mdt) 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);
}

View File

@ -1,4 +1,3 @@
/* recSel.c */
/* share/src/rec $Id$ */
@ -41,14 +40,12 @@
#include <lstLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <dbDefs.h>
#include <dbFldTypes.h>
#include <errMdef.h>
#include <link.h>
#include <recSup.h>
#include <special.h>
#include <selRecord.h>
/* 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->nsev<MAJOR_ALARM) {
psel->nsta = 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->nsev<psel->hhsv){
if (psel->val > psel->hihi){
psel->lalm = psel->val;
psel->nsta = HIHI_ALARM;
psel->nsev = psel->hhsv;
return;
}
}
/* alarm condition lolo */
if (psel->nsev<psel->llsv){
if (psel->val < psel->lolo){
psel->lalm = psel->val;
psel->nsta = LOLO_ALARM;
psel->nsev = psel->llsv;
return;
}
}
/* alarm condition high */
if (psel->nsev<psel->hsv){
if (psel->val > psel->high){
psel->lalm = psel->val;
psel->nsta = HIGH_ALARM;
psel->nsev =psel->hsv;
return;
}
}
/* alarm condition lolo */
if (psel->nsev<psel->lsv){
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; i<SEL_MAX; i++, plink++, pvalue++) {
if(plink->type==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;
}

View File

@ -1,4 +1,3 @@
/* recState.c */
/* share/src/rec $Id$ */
@ -37,8 +36,6 @@
#include <stdioLib.h>
#include <lstLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <dbDefs.h>
#include <dbFldTypes.h>
@ -46,7 +43,6 @@
#include <errMdef.h>
#include <link.h>
#include <recSup.h>
#include <special.h>
#include <stateRecord.h>
/* 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);
}

View File

@ -1,4 +1,3 @@
/* recSub.c */
/* share/src/rec $Id$ */
@ -35,17 +34,18 @@
#include <vxWorks.h>
#include <types.h>
#include <stdioLib.h>
#include <lstLib.h>
#include <symLib.h>
#include <sysSymTbl.h> /* for sysSymTbl*/
#include <a_out.h> /* for N_TEXT */
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <dbDefs.h>
#include <dbFldTypes.h>
#include <devSup.h>
#include <errMdef.h>
#include <link.h>
#include <recSup.h>
#include <special.h>
#include <subRecord.h>
/* 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->nsev<psub->hhsv){
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->nsev<psub->llsv){
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->nsev<psub->hsv){
if (psub->val > psub->high){
psub->lalm = psub->val;
psub->nsta = HIGH_ALARM;
psub->nsev =psub->hsv;
return;
}
}
/* alarm condition lolo */
if (psub->nsev<psub->lsv){
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->nsev<MAJOR_ALARM) {
psub->nsta = BAD_SUB_ALARM;
psub->nsev = MAJOR_ALARM;
}
return(0);
}
status = psubroutine(psub,callback);
if(status < 0){
if (psub->nsev<psub->brsv){
psub->nsta = SOFT_ALARM;
psub->nsev = psub->brsv;
}
}
return(status);
}

View File

@ -1,4 +1,3 @@
/* recTimer.c */
/* share/src/rec $Id$ */
@ -48,7 +47,6 @@
#include <lstLib.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <dbDefs.h>
#include <dbFldTypes.h>
@ -56,7 +54,6 @@
#include <errMdef.h>
#include <link.h>
#include <recSup.h>
#include <special.h>
#include <timerRecord.h>
/* 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->nsev<MAJOR_ALARM) {
ptimer->nsta = 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->nsev<MAJOR_ALARM) {
ptimer->nsta = 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;
}

View File

@ -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 <types.h>
#include <stdioLib.h>
#include <lstLib.h>
#include <math.h>
#include <alarm.h>
#include <cvtTable.h>
#include <dbAccess.h>
#include <dbDefs.h>
#include <dbFldTypes.h>
@ -62,7 +60,6 @@
#include <errMdef.h>
#include <link.h>
#include <recSup.h>
#include <special.h>
#include <waveformRecord.h>
/* 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;
}