asynStatus NDPluginCircularBuff::calculateTrigger(NDArray *pArray, int *trig) { NDAttribute *trigger; char triggerString[256]; double triggerValue; double calcResult; int status; int preTrigger, postTrigger, currentImage, triggered; static const char *functionName="calculateTrigger"; *trig = 0; getIntegerParam(NDCircBuffPreTrigger, &preTrigger); getIntegerParam(NDCircBuffPostTrigger, &postTrigger); getIntegerParam(NDCircBuffCurrentImage, ¤tImage); getIntegerParam(NDCircBuffTriggered, &triggered); triggerCalcArgs_[0] = epicsNAN; triggerCalcArgs_[1] = epicsNAN; triggerCalcArgs_[2] = preTrigger; triggerCalcArgs_[3] = postTrigger; triggerCalcArgs_[4] = currentImage; triggerCalcArgs_[5] = triggered; getStringParam(NDCircBuffTriggerA, sizeof(triggerString), triggerString); trigger = pArray->pAttributeList->find(triggerString); if (trigger != NULL) { status = trigger->getValue(NDAttrFloat64, &triggerValue); if (status == asynSuccess) { triggerCalcArgs_[0] = triggerValue; } } getStringParam(NDCircBuffTriggerB, sizeof(triggerString), triggerString); trigger = pArray->pAttributeList->find(triggerString); if (trigger != NULL) { status = trigger->getValue(NDAttrFloat64, &triggerValue); if (status == asynSuccess) { triggerCalcArgs_[1] = triggerValue; } } setDoubleParam(NDCircBuffTriggerAVal, triggerCalcArgs_[0]); setDoubleParam(NDCircBuffTriggerBVal, triggerCalcArgs_[1]); status = calcPerform(triggerCalcArgs_, &calcResult, triggerCalcPostfix_); if (status) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s::%s error evaluating expression=%s\n", driverName, functionName, calcErrorStr(status)); return asynError; } if (!isnan(calcResult) && !isinf(calcResult) && (calcResult != 0)) *trig = 1; setDoubleParam(NDCircBuffTriggerCalcVal, calcResult); return asynSuccess; }
static void execOutput(calcoutRecord *prec) { /* Determine output data */ switch(prec->dopt) { case calcoutDOPT_Use_VAL: prec->oval = prec->val; break; case calcoutDOPT_Use_OVAL: if (calcPerform(&prec->a, &prec->oval, prec->orpc)) { recGblSetSevr(prec, CALC_ALARM, INVALID_ALARM); } else { prec->udf = isnan(prec->oval); } break; } if (prec->udf){ recGblSetSevr(prec, UDF_ALARM, prec->udfs); } /* Check to see what to do if INVALID */ if (prec->nsev < INVALID_ALARM ) { /* Output the value */ writeValue(prec); /* post output event if set */ if (prec->epvt) postEvent(prec->epvt); } else switch (prec->ivoa) { case menuIvoaContinue_normally: writeValue(prec); /* post output event if set */ if (prec->epvt) postEvent(prec->epvt); break; case menuIvoaDon_t_drive_outputs: break; case menuIvoaSet_output_to_IVOV: prec->oval = prec->ivov; writeValue(prec); /* post output event if set */ if (prec->epvt) postEvent(prec->epvt); break; default: recGblRecordError(S_db_badField, (void *)prec, "calcout:process Illegal IVOA field"); } }
static long process(calcoutRecord *prec) { rpvtStruct *prpvt = prec->rpvt; int doOutput; if (!prec->pact) { prec->pact = TRUE; /* if some links are CA, check connections */ if (prpvt->caLinkStat != NO_CA_LINKS) { checkLinks(prec); } if (fetch_values(prec) == 0) { if (calcPerform(&prec->a, &prec->val, prec->rpcl)) { recGblSetSevr(prec, CALC_ALARM, INVALID_ALARM); } else { prec->udf = isnan(prec->val); } } checkAlarms(prec); /* check for output link execution */ switch (prec->oopt) { case calcoutOOPT_Every_Time: doOutput = 1; break; case calcoutOOPT_On_Change: doOutput = ! (fabs(prec->pval - prec->val) <= prec->mdel); break; case calcoutOOPT_Transition_To_Zero: doOutput = ((prec->pval != 0.0) && (prec->val == 0.0)); break; case calcoutOOPT_Transition_To_Non_zero: doOutput = ((prec->pval == 0.0) && (prec->val != 0.0)); break; case calcoutOOPT_When_Zero: doOutput = (prec->val == 0.0); break; case calcoutOOPT_When_Non_zero: doOutput = (prec->val != 0.0); break; default: doOutput = 0; break; } prec->pval = prec->val; if (doOutput) { if (prec->odly > 0.0) { prec->dlya = 1; recGblGetTimeStamp(prec); db_post_events(prec, &prec->dlya, DBE_VALUE); callbackRequestProcessCallbackDelayed(&prpvt->doOutCb, prec->prio, prec, (double)prec->odly); return 0; } else { prec->pact = FALSE; execOutput(prec); if (prec->pact) return 0; prec->pact = TRUE; } } recGblGetTimeStamp(prec); } else { /* pact == TRUE */ if (prec->dlya) { prec->dlya = 0; recGblGetTimeStamp(prec); db_post_events(prec, &prec->dlya, DBE_VALUE); /* Make pact FALSE for asynchronous device support*/ prec->pact = FALSE; execOutput(prec); if (prec->pact) return 0; prec->pact = TRUE; } else {/*Device Support is asynchronous*/ writeValue(prec); recGblGetTimeStamp(prec); } } monitor(prec); recGblFwdLink(prec); prec->pact = FALSE; return 0; }