Пример #1
0
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, &currentImage);
    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;
}
Пример #2
0
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");
    }
}
Пример #3
0
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;
}