diff --git a/src/rec/recAi.c b/src/rec/recAi.c index 6f7a7a67d..5a360e529 100644 --- a/src/rec/recAi.c +++ b/src/rec/recAi.c @@ -408,7 +408,10 @@ static void monitor(pai) /* send out monitors connected to the value field */ if (monitor_mask){ db_post_events(pai,&pai->val,monitor_mask); - db_post_events(pai,&pai->rval,monitor_mask); + if(pai->oraw != pai->rval) { + db_post_events(pai,&pai->rval,monitor_mask); + pai->oraw = pai->rval; + } } return; } diff --git a/src/rec/recAo.c b/src/rec/recAo.c index 9af9ad1ba..6401bb5ef 100644 --- a/src/rec/recAo.c +++ b/src/rec/recAo.c @@ -112,9 +112,6 @@ struct aodset { /* analog input dset */ DEVSUPFUN special_linconv; }; -/* the following definitions must match those in choiceGbl.ascii */ -#define SUPERVISORY 0 -#define CLOSED_LOOP 1 /* the following definitions must match those in choiceRec.ascii */ #define OUTPUT_FULL 0 @@ -143,8 +140,6 @@ static long report(fp,paddr) pao->eguf,pao->egul,pao->egu)) return(-1); if(fprintf(fp,"HOPR %-12.4G LOPR %-12.4G\n", pao->hopr,pao->lopr)) return(-1); - if(fprintf(fp,"AOFF %-12.4G ASLO %-12.4G\n", - pao->aoff,pao->aslo)) return(-1); if(recGblReportLink(fp,"FLNK",&(pao->flnk))) return(-1); if(fprintf(fp,"HIHI %-12.4G HIGH %-12.4G LOW %-12.4G LOLO %-12.4G\n", pao->hihi,pao->high,pao->low,pao->lolo)) return(-1); @@ -202,9 +197,13 @@ static long process(paddr) recGblRecordError(S_dev_missingSup,pao,"write_ao"); return(S_dev_missingSup); } - if(pao->pact == 0) convert(pao); - status=(*pdset->write_ao)(pao); /* write the new value */ - pao->pact = TRUE; + if(pao->pact == FALSE) { + convert(pao); + if(pao->oraw != pao->oval) status=(*pdset->write_ao)(pao); + } else { + 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(0); @@ -407,8 +406,17 @@ static void monitor(pao) /* send out monitors connected to the value field */ if (monitor_mask){ db_post_events(pao,&pao->val,monitor_mask); + } + if(pao->oraw != pao->rval) { + monitor_mask |= DBE_VALUE; db_post_events(pao,&pao->rval,monitor_mask); - db_post_events(pao,&pao->rbv,monitor_mask); + db_post_events(pao,&pao->oval,monitor_mask); + pao->oraw = pao->rval; + } + if(pao->orbv != pao->rbv) { + monitor_mask |= DBE_VALUE; + db_post_events(pao,&pao->rbv,monitor_mask); + pao->orbv = pao->rbv; } return; } @@ -416,55 +424,57 @@ static void monitor(pao) static void convert(pao) struct aoRecord *pao; { + float value; + /* 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; + long status; 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 */ + status = dbGetLink(&pao->dol.value,DBR_FLOAT,&value,&options,&nRequest); pao->pact = save_pact; - } + if(status) { + if(pao->nsevnsta = LINK_ALARM; + pao->nsev=VALID_ALARM; + } + return; + } + if (pao->oif == OUTPUT_INCREMENTAL) value += pao->val; + } else value = pao->val; + /* check drive limits */ + if(pao->drvh > pao->drvl) { + if (value > pao->drvh) value = pao->drvh; + else if (value < pao->drvl) value = pao->drvl; + } + pao->val = value; + + /* now set value equal to desired output value */ /* apply the output rate of change */ if (pao->oroc){ float diff; - diff = pao->val - pao->oval; + diff = value - 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; + if (pao->oroc < -diff) value = pao->oval - pao->oroc; + }else if (pao->oroc < diff) value = pao->oval + pao->oroc; } + pao->oval = value; - /* check drive limits */ - if (pao->oval > pao->drvh) pao->oval = pao->drvh; - else if (pao->oval < pao->drvl) pao->oval = pao->drvl; /* convert */ if (pao->linr == LINEAR){ if (pao->eslo == 0) pao->rval = 0; - else pao->rval = (pao->oval - pao->egul) / pao->eslo; + else pao->rval = (value - pao->egul) / pao->eslo; }else{ - pao->rval = pao->oval; + pao->rval = value; } } diff --git a/src/rec/recBi.c b/src/rec/recBi.c index ef1e7736f..761db4b8d 100644 --- a/src/rec/recBi.c +++ b/src/rec/recBi.c @@ -59,7 +59,6 @@ #include #include #include - /* Create RSET - Record Support Entry Table*/ long report(); #define initialize NULL @@ -101,7 +100,6 @@ struct bidset { /* binary input dset */ DEVSUPFUN get_ioint_info; DEVSUPFUN read_bi;/*(-1,0,1)=>(failure,success,don't Continue*/ }; - void alarm(); void monitor(); @@ -199,7 +197,7 @@ static long get_enum_str(paddr,pstring) } else { strcpy(pstring,"Illegal_Value"); } - return(0L); + return(0); } static long get_enum_strs(paddr,pes) @@ -212,7 +210,7 @@ static long get_enum_strs(paddr,pes) bzero(pes->strs,sizeof(pes->strs)); strncpy(pes->strs[0],pbi->znam,sizeof(pbi->znam)); strncpy(pes->strs[1],pbi->onam,sizeof(pbi->onam)); - return(0L); + return(0); } static void alarm(pbi) @@ -288,7 +286,10 @@ static void monitor(pbi) /* send out monitors connected to the value field */ if (monitor_mask){ db_post_events(pbi,&pbi->val,monitor_mask); - db_post_events(pbi,&pbi->rval,monitor_mask); + } + if(pbi->oraw!=pbi->rval) { + db_post_events(pbi,&pbi->rval,monitor_mask|=DBE_VALUE); + pbi->oraw = pbi->rval; } return; } diff --git a/src/rec/recBo.c b/src/rec/recBo.c index 4f139c5af..d9b91e976 100644 --- a/src/rec/recBo.c +++ b/src/rec/recBo.c @@ -113,29 +113,30 @@ struct bodset { /* binary output dset */ DEVSUPFUN write_bo;/*(-1,0,1)=>(failure,success,don't Continue*/ }; -/* the following definitions must match those in choiceGbl.ascii */ -#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; + struct boRecord *pbo = (struct boRecord *)(pcallback->dbAddr.precord); - pcallback->completion = TRUE; - dbPutField(&(pcallback->dbAddr),DBR_SHORT,&value,1L); + dbScanLock(pbo); + pbo->val = 1; + (void)process(&(pcallback->dbAddr)); + dbScanUnlock(pbo); } static long report(fp,paddr) @@ -177,7 +178,7 @@ static long init_record(pbo) if( pdset->init_record ) { if((status=(*pdset->init_record)(pbo,process))) return(status); } - pcallback = (struct callback *)(calloc(1,sizeof(struct callback *))); + pcallback = (struct callback *)(calloc(1,sizeof(struct callback))); pbo->dpvt = (caddr_t)pcallback; pcallback->callback = myCallback; if(dbNameToAddr(pbo->name,&(pcallback->dbAddr))) { @@ -195,10 +196,7 @@ static long process(paddr) struct boRecord *pbo=(struct boRecord *)(paddr->precord); struct bodset *pdset = (struct bodset *)(pbo->dset); long status; - long nRequest; - struct callback *pcallback; int wait_time; - short val; if( (pdset==NULL) || (pdset->write_bo==NULL) ) { pbo->pact=TRUE; @@ -209,38 +207,37 @@ 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; - status = dbGetLink(&pbo->dol.value,DBF_SHORT,&val,&nRequest); - if(status == 0){ - if (val != 0) pbo->val = 1; - else pbo->val = 0; - } + long options=0; + long nRequest=1; + short savepact=pbo->pact; + + pbo->pact = TRUE; + (void)dbGetLink(&pbo->dol.value.db_link,pbo, + DBR_SHORT,&(pbo->val),&options,&nRequest); + pbo->pact = savepact; } - status=(*pdset->write_bo)(pbo); /* write the new value */ - pbo->pact = TRUE; + if(pbo->lalm != pbo->val) {/*we have a change */ + 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(0); + /* status is one if an asynchronous record is being processed*/ + 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 { + wait_time = (int)(pbo->high) * vxTicksPerSecond; /* seconds to ticks */ + if(pbo->val==1 && wait_time>0) { + struct callback *pcallback; + + pcallback = (struct callback *)(pbo->dpvt); if(pcallback->wd_id==NULL) pcallback->wd_id = wdCreate(); - wdStart(pcallback->wd_id,wait_time,callbackRequest,pcallback); - } - } + wdStart(pcallback->wd_id,wait_time,callbackRequest,pcallback); + } + } else pbo->pact = TRUE; /* check for alarms */ alarm(pbo); - - /* check event list */ monitor(pbo); - /* process the forward scan link record */ if (pbo->flnk.type==DB_LINK) dbScanPassive(&pbo->flnk.value.db_link.pdbAddr); @@ -273,7 +270,7 @@ static long get_enum_str(paddr,pstring) } else { strcpy(pstring,"Illegal_Value"); } - return(0L); + return(0); } static long get_enum_strs(paddr,pes) @@ -286,7 +283,7 @@ static long get_enum_strs(paddr,pes) bzero(pes->strs,sizeof(pes->strs)); strncpy(pes->strs[0],pbo->znam,sizeof(pbo->znam)); strncpy(pes->strs[1],pbo->onam,sizeof(pbo->onam)); - return(0L); + return(0); } static void alarm(pbo) @@ -362,8 +359,14 @@ static void monitor(pbo) /* 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); } + if(pbo->oraw!=pbo->rval) { + db_post_events(pbo,&pbo->rval,monitor_mask|=DBE_VALUE); + pbo->oraw = pbo->rval; + } + if(pbo->orbv!=pbo->rbv) { + db_post_events(pbo,&pbo->rbv,monitor_mask|=DBE_VALUE); + pbo->orbv = pbo->rbv; + } return; } diff --git a/src/rec/recCalc.c b/src/rec/recCalc.c index a8aeee82c..c4f11b073 100644 --- a/src/rec/recCalc.c +++ b/src/rec/recCalc.c @@ -71,6 +71,7 @@ #include #include #include +#include /* Create RSET - Record Support Entry Table*/ long report(); @@ -262,15 +263,11 @@ static long process(paddr) pcalc->pact = TRUE; fetch_values(pcalc); if(do_calc(pcalc)) { - if(pcalc->nsevnsevnsta = CALC_ALARM; - pcalc->nsev = MAJOR_ALARM; + pcalc->nsev = VALID_ALARM; } } - if(pcalc->hopr!=pcalc->lopr) { - if(pcalc->val>pcalc->hopr) pcalc->val = pcalc->hopr; - if(pcalc->vallopr) pcalc->val = pcalc->lopr; - } /* check for alarms */ alarm(pcalc); /* check event list */ @@ -339,6 +336,9 @@ static void monitor(pcalc) unsigned short monitor_mask; float delta; short stat,sevr,nsta,nsev; + float *pnew; + float *pprev; + int i; /* get previous stat and sevr and new stat and sevr*/ stat=pcalc->stat; @@ -388,6 +388,13 @@ static void monitor(pcalc) if (monitor_mask){ db_post_events(pcalc,&pcalc->val,monitor_mask); } + /* check all input fields for changes*/ + for(i=0, pnew=&pcalc->a, pprev=&pcalc->la; i<6; i++, pnew++, pprev++) { + if(*pnew != *pprev) { + db_post_events(pcalc,pnew,monitor_mask|=DBE_VALUE); + *pprev = *pnew; + } + } return; } @@ -416,61 +423,6 @@ double acos(),asin(),atan(); double cos(),sin(),tan(); double cosh(),sinh(),tanh(); -/* defines for element table */ -#define FETCH_A 0 -#define FETCH_B 1 -#define FETCH_C 2 -#define FETCH_D 3 -#define FETCH_E 4 -#define FETCH_F 5 -#define ACOS 6 -#define ASIN 7 -#define ATAN 8 -#define COS 9 -#define COSH 10 -#define SIN 11 -#define STORE_A 12 -#define STORE_B 13 -#define STORE_C 14 -#define STORE_D 15 -#define STORE_E 16 -#define STORE_F 17 -#define RIGHT_SHIFT 18 -#define LEFT_SHIFT 19 -#define SINH 20 -#define TAN 21 -#define TANH 22 -#define LOG_2 23 -#define COND_ELSE 24 -#define ABS_VAL 25 -#define UNARY_NEG 26 -#define SQU_RT 27 -#define LOG_10 28 -#define LOG_E 29 -#define RANDOM 30 -/* -#define 31 -*/ -#define ADD 32 -#define SUB 33 -#define MULT 34 -#define DIV 35 -#define EXPON 36 -#define MODULO 37 -#define BIT_OR 38 -#define BIT_AND 39 -#define BIT_EXCL_OR 40 -#define GR_OR_EQ 41 -#define GR_THAN 42 -#define LESS_OR_EQ 43 -#define LESS_THAN 44 -#define NOT_EQ 45 -#define EQUAL 46 -#define REL_OR 47 -#define REL_AND 48 -#define PAREN -1 -#define END_STACK -1 - /* * DO_CALC * @@ -799,390 +751,3 @@ static double random() /* between 0 - 1 */ return(randy); } - -/* - * POSTFIX.C - * - * Subroutines used to convert an infix expression to a postfix expression - * - * Author: Bob Dalesio - * Date: 12-12-86 - * @(#)postfix.c 1.1 9/21/88 - * - * Control System Software for the GTA Project - * - * Copyright 1988, 1989, the Regents of the University of California. - * - * This software was produced under a U.S. Government contract - * (W-7405-ENG-36) at the Los Alamos National Laboratory, which is - * operated by the University of California for the U.S. Department - * of Energy. - * - * Developed by the Controls and Automation Group (AT-8) - * Accelerator Technology Division - * Los Alamos National Laboratory - * - * Direct inqueries to: - * Andy Kozubal, AT-8, Mail Stop H820 - * Los Alamos National Laboratory - * Los Alamos, New Mexico 87545 - * Phone: (505) 667-6508 - * E-mail: kozubal@k2.lanl.gov - * - * Modification Log: - * ----------------- - * .01 01-11-89 lrd added right shift and left shift operations - * .02 01-13-89 lrd modified to load into IOCs - * .03 02-01-89 lrd added trigonometric functions - * .04 04-05-89 lrd fixed the order of some operations in the - * element table and added a warning label -*/ - -/* - * Subroutines - * - * find_element finds a symbolic element in the expression element tbl - * args - * pbuffer pointer to the infox expression element - * pelement pointer to the expression element table entry - * pno_bytes pointer to the size of this element - * returns - * TRUE element found - * FALSE element not found - * get_element finds the next expression element in the infix expr - * args - * pinfix pointer into the infix expression - * pelement pointer to the expression element table - * pno_bytes size of the element in the infix expression - * returns - * FINE found an expression element - * VARIABLE found a database reference - * UNKNOWN_ELEMENT unknown element found in the infix expression - * postfix convert an algebraic expression to symbolic postfix - * args - * pinfix the algebraic expression - * ppostfix the symbolic postfix expression - * returns - * 0 successful - * -1 not successful - */ - -/* element types */ -#define OPERAND 0 -#define UNARY_OPERATOR 1 -#define BINARY_OPERATOR 2 -#define EXPR_TERM 3 -#define COND 4 -#define CLOSE_PAREN 5 -#define CONDITIONAL 6 -#define ELSE 7 -#define TRASH 8 - -/* flags end of element table */ -#define END_ELEMENTS -1 - -/* parsing return values */ -#define FINE 0 -#define UNKNOWN_ELEMENT -1 -#define END -2 - -/* - * element table - * - * structure of an element - */ -struct expression_element{ - char element[10]; /* character representation of an element */ - char in_stack_pri; /* priority in translation stack */ - char in_coming_pri; /* priority when first checking */ - char type; /* element type */ - char code; /* postfix representation */ -}; - -/* - * NOTE: DO NOT CHANGE WITHOUT READING THIS NOTICE !!!!!!!!!!!!!!!!!!!! - * Because the routine that looks for a match in this table takes the first - * match it finds, elements whose designations are contained in other elements - * MUST come first in this list. (e.g. ABS will match A if A preceeds ABS and - * then try to find BS therefore ABS must be first in this list - */ -static struct expression_element elements[] = { -/* element i_s_p i_c_p type_element internal_rep */ -"ABS", 7, 8, UNARY_OPERATOR, ABS_VAL, /* absolute value */ -"NOT", 7, 8, UNARY_OPERATOR, UNARY_NEG, /* unary negate */ -"SQR", 7, 8, UNARY_OPERATOR, SQU_RT, /* square root */ -"LOG", 7, 8, UNARY_OPERATOR, LOG_10, /* log 10 */ -"LOGE", 7, 8, UNARY_OPERATOR, LOG_E, /* log E */ -"ACOS", 7, 8, UNARY_OPERATOR, ACOS, /* arc cosine */ -"ASIN", 7, 8, UNARY_OPERATOR, ASIN, /* arc sine */ -"ATAN", 7, 8, UNARY_OPERATOR, ATAN, /* arc tangent */ -"COS", 7, 8, UNARY_OPERATOR, COS, /* cosine */ -"COSH", 7, 8, UNARY_OPERATOR, COSH, /* hyperbolic cosine */ -"SIN", 7, 8, UNARY_OPERATOR, SIN, /* sine */ -"SINH", 7, 8, UNARY_OPERATOR, SINH, /* hyperbolic sine */ -"TAN", 7, 8, UNARY_OPERATOR, TAN, /* tangent */ -"TANH", 7, 8, UNARY_OPERATOR, TANH, /* hyperbolic tangent*/ -"RNDM", 0, 0, OPERAND, RANDOM, /* Random Number */ -"OR", 1, 1, BINARY_OPERATOR,BIT_OR, /* or */ -"AND", 2, 2, BINARY_OPERATOR,BIT_AND, /* and */ -"XOR", 1, 1, BINARY_OPERATOR,BIT_EXCL_OR, /* exclusive or */ -"A", 0, 0, OPERAND, FETCH_A, /* fetch var A */ -"B", 0, 0, OPERAND, FETCH_B, /* fetch var B */ -"C", 0, 0, OPERAND, FETCH_C, /* fetch var C */ -"D", 0, 0, OPERAND, FETCH_D, /* fetch var D */ -"E", 0, 0, OPERAND, FETCH_E, /* fetch var E */ -"F", 0, 0, OPERAND, FETCH_F, /* fetch var F */ -"a", 0, 0, OPERAND, FETCH_A, /* fetch var A */ -"b", 0, 0, OPERAND, FETCH_B, /* fetch var B */ -"c", 0, 0, OPERAND, FETCH_C, /* fetch var C */ -"d", 0, 0, OPERAND, FETCH_D, /* fetch var D */ -"e", 0, 0, OPERAND, FETCH_E, /* fetch var E */ -"f", 0, 0, OPERAND, FETCH_F, /* fetch var F */ -"?", 0, 0, CONDITIONAL, COND_ELSE, /* conditional */ -":", 0, 0, ELSE, COND_ELSE, /* else */ -"(", 0, 8, UNARY_OPERATOR, PAREN, /* open paren */ -"^", 6, 6, BINARY_OPERATOR,EXPON, /* exponentiation */ -"**", 6, 6, BINARY_OPERATOR,EXPON, /* exponentiation */ -"+", 4, 4, BINARY_OPERATOR,ADD, /* addition */ -"-", 4, 4, BINARY_OPERATOR,SUB, /* subtraction */ -"*", 5, 5, BINARY_OPERATOR,MULT, /* multiplication */ -"/", 5, 5, BINARY_OPERATOR,DIV, /* division */ -"%", 5, 5, BINARY_OPERATOR,MODULO, /* modulo */ -")", 0, 0, CLOSE_PAREN, PAREN, /* close paren */ -"||", 1, 1, BINARY_OPERATOR,REL_OR, /* or */ -"|", 1, 1, BINARY_OPERATOR,BIT_OR, /* or */ -"&&", 2, 2, BINARY_OPERATOR,REL_AND, /* and */ -"&", 2, 2, BINARY_OPERATOR,BIT_AND, /* and */ -">>", 2, 2, BINARY_OPERATOR,RIGHT_SHIFT, /* right shift */ -">=", 3, 3, BINARY_OPERATOR,GR_OR_EQ, /* greater or equal*/ -">", 3, 3, BINARY_OPERATOR,GR_THAN, /* greater than */ -"<<", 2, 2, BINARY_OPERATOR,LEFT_SHIFT, /* left shift */ -"<=", 3, 3, BINARY_OPERATOR,LESS_OR_EQ,/* less or equal to*/ -"<", 3, 3, BINARY_OPERATOR,LESS_THAN, /* less than */ -"#", 3, 3, BINARY_OPERATOR,NOT_EQ, /* not equal */ -"=", 3, 3, BINARY_OPERATOR,EQUAL, /* equal */ -"" -}; - -/* - * FIND_ELEMENT - * - * find the pointer to an entry in the element table - */ -static find_element(pbuffer,pelement,pno_bytes) -#define SAME 0 - char *pbuffer; - struct expression_element **pelement; - short *pno_bytes; - { - - /* compare the string to each element in the element table */ - *pelement = &elements[0]; - while ((*pelement)->element[0] != NULL){ - if (strncmp(pbuffer,(*pelement)->element, - strlen((*pelement)->element)) == SAME){ - *pno_bytes += strlen((*pelement)->element); - return(TRUE); - } - *pelement += 1; - } - return(FALSE); - } - -/* - * GET_ELEMENT - * - * get an expression element - */ -static get_element(pinfix,pelement,pno_bytes) -char *pinfix; -struct expression_element **pelement; -short *pno_bytes; -{ - - /* get the next expression element from the infix expression */ - if (*pinfix == NULL) return(END); - *pno_bytes = 0; - while (*pinfix == 0x20){ - *pno_bytes += 1; - pinfix++; - } - if (!find_element(pinfix,pelement,pno_bytes)) - return(UNKNOWN_ELEMENT); - return(FINE); - - -} - -/* - * POSTFIX - * - * convert an infix expression to a postfix expression - */ -static long postfix(pinfix,ppostfix,perror) -char *pinfix; -char *ppostfix; -short *perror; -{ - short got_if; - short got_else; - short no_bytes; - short operand_needed; - short new_expression; - struct expression_element stack[80]; - struct expression_element *pelement; - struct expression_element *pstacktop; - - /* place the expression elements into postfix */ - got_if = FALSE; - got_else = FALSE; - operand_needed = TRUE; - new_expression = TRUE; - pstacktop = &stack[0]; - while (get_element(pinfix,&pelement,&no_bytes) != END){ - - pinfix += no_bytes; - switch (pelement->type){ - - case OPERAND: - if (!operand_needed){ - *perror = 5; - return(-1); - } - - /* add operand to the expression */ - *ppostfix++ = pelement->code; - - operand_needed = FALSE; - new_expression = FALSE; - break; - - case BINARY_OPERATOR: - if (operand_needed){ - *perror = 4; - return(-1); - } - - /* add operators of higher or equal priority to */ - /* postfix notation */ - while ((pstacktop->in_stack_pri >= pelement->in_coming_pri) - && (pstacktop >= &stack[1])){ - *ppostfix++ = pstacktop->code; - pstacktop--; - } - - /* add new operator to stack */ - pstacktop++; - *pstacktop = *pelement; - - operand_needed = TRUE; - break; - - case UNARY_OPERATOR: - if (!operand_needed){ - *perror = 5; - return(-1); - } - - /* add operators of higher or equal priority to */ - /* postfix notation */ - while ((pstacktop->in_stack_pri >= pelement->in_coming_pri) - && (pstacktop >= &stack[1])){ - *ppostfix++ = pstacktop->code; - pstacktop--; - } - - /* add new operator to stack */ - pstacktop++; - *pstacktop = *pelement; - - new_expression = FALSE; - break; - - case CLOSE_PAREN: - if (operand_needed){ - *perror = 4; - return(-1); - } - - /* add operators to postfix until matching paren */ - while (pstacktop->element[0] != '('){ - if (pstacktop == &stack[1]){ - *perror = 6; - return(-1); - } - *ppostfix++ = pstacktop->code; - pstacktop--; - } - pstacktop--; /* remove ( from stack */ - break; - - /* conditional includes expression termination */ - case CONDITIONAL: - if (got_if){ - *perror = 9; - return(-1); - } - got_if = TRUE; - - /* else includes expression termination */ - case ELSE: - if (pelement->type == ELSE){ - if (!got_if){ - *perror = 11; - return(-1); - } - if (got_else){ - *perror = 10; - return(-1); - } - got_else = TRUE; - } - - case EXPR_TERM: - if (operand_needed && !new_expression){ - *perror = 4; - return(-1); - } - - /* add all operators on stack to postfix */ - while (pstacktop >= &stack[1]){ - if (pstacktop->element[0] == '('){ - *perror = 6; - return(-1); - } - *ppostfix++ = pstacktop->code; - pstacktop--; - } - - /* add new element to the postfix expression */ - *ppostfix++ = pelement->code; - - operand_needed = TRUE; - new_expression = TRUE; - break; - - - default: - *perror = 8; - return(-1); - } - } - if (operand_needed){ - *perror = 4; - return(-1); - } - - /* add all operators on stack to postfix */ - while (pstacktop >= &stack[1]){ - if (pstacktop->element[0] == '('){ - *perror = 6; - return(-1); - } - *ppostfix++ = pstacktop->code; - pstacktop--; - } - *ppostfix = END_STACK; - - return(0); -} diff --git a/src/rec/recCompress.c b/src/rec/recCompress.c index e28f46f58..182201d79 100644 --- a/src/rec/recCompress.c +++ b/src/rec/recCompress.c @@ -185,7 +185,7 @@ static long get_value(pcompress,pvdes) struct valueDes *pvdes; { pvdes->field_type = DBF_FLOAT; - pvdes->no_elements=pcompress->nsam; + pvdes->no_elements=pcompress->nuse; (float *)(pvdes->pvalue) = pcompress->bptr; return(0); } @@ -270,11 +270,6 @@ static long process(paddr) { 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->pact = TRUE; @@ -287,6 +282,12 @@ static long process(paddr) } status=0; } else { + struct dbAddr *pdbAddr = + (struct dbAddr *)(pcompress->inp.value.db_link.pdbAddr); + long options=0; + long no_elements=pdbAddr->no_elements; + int alg=pcompress->alg; + (void)dbGetLink(&pcompress->inp.value.db_link,pcompress,DBR_FLOAT,pcompress->wptr, &options,&no_elements); if(alg==AVERAGE) { @@ -297,7 +298,7 @@ static long process(paddr) } else if(pdbAddr->no_elements>1) { status = compress_array(pcompress,pcompress->wptr,no_elements); }else if(no_elements==1){ - status = compress_value(pcompress); + status = compress_value(pcompress,pcompress->wptr); }else status=1; } @@ -410,7 +411,7 @@ long no_elements; /* compress N to 1 keeping the lowest value */ for (i = 0; i < nnew; i++){ value = *psource++; - for (j = 1; j < pcompress->n; j++, psource++){ + for (j = 1; j < n; j++, psource++){ if (value > *psource) value = *psource; } put_value(pcompress,&value,1); @@ -420,7 +421,7 @@ long no_elements; /* compress N to 1 keeping the highest value */ for (i = 0; i < nnew; i++){ value = *psource++; - for (j = 1; j < pcompress->n; j++, psource++){ + for (j = 1; j < n; j++, psource++){ if (value < *psource) value = *psource; } put_value(pcompress,&value,1); @@ -430,8 +431,9 @@ long no_elements; /* compress N to 1 keeping the average value */ for (i = 0; i < nnew; i++){ value = 0; - for (j = 0; j < pcompress->n; j++, psource++) + for (j = 0; j < n; j++, psource++) value += *psource; + value /= n; put_value(pcompress,&value,1); } break; diff --git a/src/rec/recMbbi.c b/src/rec/recMbbi.c index 7adb063a5..8b1ccc85f 100644 --- a/src/rec/recMbbi.c +++ b/src/rec/recMbbi.c @@ -62,7 +62,6 @@ #include #include #include - /* Create RSET - Record Support Entry Table*/ long report(); #define initialize NULL @@ -79,7 +78,6 @@ long get_enum_str(); #define get_graphic_double NULL #define get_control_double NULL long get_enum_strs(); - struct rset mbbiRSET={ RSETNUMBER, report, @@ -97,7 +95,6 @@ struct rset mbbiRSET={ get_graphic_double, get_control_double, get_enum_strs }; - struct mbbidset { /* multi bit binary input dset */ long number; DEVSUPFUN report; @@ -106,7 +103,6 @@ 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(); @@ -354,7 +350,10 @@ static void monitor(pmbbi) /* send out monitors connected to the value field */ if (monitor_mask){ db_post_events(pmbbi,&pmbbi->val,monitor_mask); + } + if(pmbbi->oraw!=pmbbi->rval) { db_post_events(pmbbi,&pmbbi->rval,monitor_mask); + pmbbi->oraw = pmbbi->rval; } return; } diff --git a/src/rec/recMbbo.c b/src/rec/recMbbo.c index 3bb850d18..eb2248042 100644 --- a/src/rec/recMbbo.c +++ b/src/rec/recMbbo.c @@ -110,9 +110,6 @@ struct mbbodset { /* multi bit binary input dset */ DEVSUPFUN write_mbbo;/*(-1,0,1)=>(failure,success,don't Continue*/ }; -/* the following definitions must match those in choiceGbl.ascii */ -#define SUPERVISORY 0 -#define CLOSED_LOOP 1 void alarm(); void monitor(); @@ -270,7 +267,7 @@ static long process(paddr) } /* fetch the desired output if there is a database link */ - if (pmbbo->dol.type == DB_LINK && pmbbo->omsl == CLOSED_LOOP){ + if (!pmbbo->pact && pmbbo->dol.type==DB_LINK && pmbbo->omsl==CLOSED_LOOP){ long options=0; long nRequest=1; short savepact=pmbbo->pact; @@ -281,36 +278,35 @@ static long process(paddr) pmbbo->pact = savepact; } - status=(*pdset->write_mbbo)(pmbbo); /* write the new value */ - pmbbo->pact = TRUE; + if(pmbbo->lalm != pmbbo->val) { /*we have a change*/ + 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); + /* 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; + /* 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; + } else pmbbo->pact = TRUE; /* 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); @@ -393,7 +389,14 @@ static void monitor(pmbbo) /* 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); + } + if(pmbbo->oraw!=pmbbo->rval) { + db_post_events(pmbbo,&pmbbo->rval,monitor_mask|=DBE_VALUE); + pmbbo->oraw = pmbbo->rval; + } + if(pmbbo->orbv!=pmbbo->rbv) { + db_post_events(pmbbo,&pmbbo->rbv,monitor_mask|=DBE_VALUE); + pmbbo->orbv = pmbbo->rbv; } return; } diff --git a/src/rec/recPid.c b/src/rec/recPid.c index c6104a8d5..73b83924a 100644 --- a/src/rec/recPid.c +++ b/src/rec/recPid.c @@ -82,9 +82,6 @@ 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(); @@ -306,6 +303,14 @@ static void monitor(ppid) if (monitor_mask){ db_post_events(ppid,&ppid->val,monitor_mask); } + if(ppid->ocva != ppid->cval) { + db_post_events(ppid,&ppid->cval,DBE_VALUE); + ppid->ocva = ppid->cval; + } + if(ppid->oout != ppid->out) { + db_post_events(ppid,&ppid->out,DBE_VALUE); + ppid->oout = ppid->out; + } return; } @@ -315,7 +320,7 @@ static void monitor(ppid) * 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 + * NOTE: KI is inverse of normal definition of 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 @@ -372,7 +377,7 @@ struct pidRecord *ppid; if (ppid->nsevstat = READ_ALARM; ppid->sevr = MAJOR_ALARM; - return(-1); + return(0); } } } @@ -408,7 +413,6 @@ struct pidRecord *ppid; ppid->dt = dt; ppid->err = e; ppid->derr = de; - ppid->val = val; ppid->cval = cval; ppid->out = out; return(0); diff --git a/src/rec/recSel.c b/src/rec/recSel.c index c1220c1f6..8fee0f87a 100644 --- a/src/rec/recSel.c +++ b/src/rec/recSel.c @@ -261,6 +261,9 @@ static void monitor(psel) unsigned short monitor_mask; float delta; short stat,sevr,nsta,nsev; + float *pnew; + float *pprev; + int i; /* get previous stat and sevr and new stat and sevr*/ stat=psel->stat; @@ -310,6 +313,13 @@ static void monitor(psel) if (monitor_mask){ db_post_events(psel,&psel->val,monitor_mask); } + /* check all input fields for changes*/ + for(i=0, pnew=&psel->a, pprev=&psel->la; i<6; i++, pnew++, pprev++) { + if(*pnew != *pprev) { + db_post_events(psel,pnew,monitor_mask|=DBE_VALUE); + *pprev = *pnew; + } + } return; } @@ -383,6 +393,15 @@ struct selRecord *psel; plink = &psel->inpa; pvalue = &psel->a; + /* If select mechanism is SELECTED only get selected input*/ + if(psel->selm == SELECTED) { + plink += psel->seln; + pvalue += psel->seln; + nRequest=1; + (void)dbGetLink(&plink->value.db_link,psel,DBR_FLOAT,pvalue,&options,&nRequest); + return; + } + /* fetch all inputs*/ for(i=0; itype==DB_LINK) { nRequest=1; diff --git a/src/rec/recState.c b/src/rec/recState.c index b9e4138ea..2928496c2 100644 --- a/src/rec/recState.c +++ b/src/rec/recState.c @@ -108,8 +108,13 @@ static long process(paddr) struct stateRecord *pstate=(struct stateRecord *)(paddr->precord); pstate->pact=TRUE; - if(pstate->mlis.count != 0) - db_post_events(pstate,&(pstate->val[0]),DBE_VALUE); + if(strncmp(pstate->oval,pstate->val,sizeof(pstate->val))) { + if(pstate->mlis.count != 0) + db_post_events(pstate,&(pstate->val[0]),DBE_VALUE); + strncpy(pstate->oval,pstate->val,sizeof(pstate->val)); + } + /* process the forward scan link record */ + if (pstate->flnk.type==DB_LINK) dbScanPassive(&pstate->flnk.value.db_link.pdbAddr); pstate->pact=FALSE; return(0); } diff --git a/src/rec/recSub.c b/src/rec/recSub.c index 0a2ef42a9..eef287fc9 100644 --- a/src/rec/recSub.c +++ b/src/rec/recSub.c @@ -156,8 +156,7 @@ static long init_record(psub) /* invoke the initialization subroutine */ psubroutine = (FUNCPTR)(psub->sadr); - status = psubroutine(psub); - if(!status) return(status); + status = psubroutine(psub,process); /* convert the subroutine name to an address and type */ /* convert the initialization subroutine name */ @@ -312,6 +311,9 @@ static void monitor(psub) unsigned short monitor_mask; float delta; short stat,sevr,nsta,nsev; + float *pnew; + float *pprev; + int i; /* get previous stat and sevr and new stat and sevr*/ stat=psub->stat; @@ -360,6 +362,13 @@ static void monitor(psub) if (monitor_mask){ db_post_events(psub,&psub->val,monitor_mask); } + /* check all input fields for changes*/ + for(i=0, pnew=&psub->a, pprev=&psub->la; i<6; i++, pnew++, pprev++) { + if(*pnew != *pprev) { + db_post_events(psub,pnew,monitor_mask|=DBE_VALUE); + *pprev = *pnew; + } + } return; } @@ -381,18 +390,10 @@ struct subRecord *psub; 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; + long status; FUNCPTR psubroutine; @@ -405,7 +406,7 @@ struct subRecord *psub; /* pointer to subroutine record */ } return(0); } - status = psubroutine(psub,callback); + status = psubroutine(psub); if(status < 0){ if (psub->nsevbrsv){ psub->nsta = SOFT_ALARM; diff --git a/src/rec/recWaveform.c b/src/rec/recWaveform.c index 2de00583b..9b0a6d90d 100644 --- a/src/rec/recWaveform.c +++ b/src/rec/recWaveform.c @@ -127,13 +127,22 @@ static long init_record(pwf) struct wfdset *pdset; long status; + /* This routine may get called twice. Once by cvt_dbaddr. Once by iocInit*/ 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]); + if(pwf->ftvl == 0) { + pwf->bptr = (char *)calloc(pwf->nelm,MAX_STRING_SIZE); + } else { + if(pwf->ftvl<0|| pwf->ftvl>DBF_ENUM) pwf->ftvl=2; + pwf->bptr = (char *)calloc(pwf->nelm,sizeofTypes[pwf->ftvl]); + } pwf->nord = 0; /* must have read_wf function defined */ + if(!(pdset = (struct wfdset *)(pwf->dset))) { + recGblRecordError(S_dev_noDSET,pwf,"wf: init_record"); + return(S_dev_noDSET); + } if( (pdset->number < 5) || (pdset->read_wf == NULL) ) { recGblRecordError(S_dev_missingSup,pwf,"wf: init_record"); return(S_dev_missingSup); @@ -176,7 +185,8 @@ static long cvt_dbaddr(paddr) paddr->pfield = (caddr_t)(pwf->bptr); paddr->no_elements = pwf->nelm; paddr->field_type = pwf->ftvl; - paddr->field_size = sizeofTypes[pwf->ftvl]; + if(pwf->ftvl==0) paddr->field_size = MAX_STRING_SIZE; + else paddr->field_size = sizeofTypes[pwf->ftvl]; paddr->dbr_field_type = pwf->ftvl; return(0); }