diff --git a/sinqEPICSApp/Db/el737Record.db b/sinqEPICSApp/Db/el737Record.db index d11f8ea..ab632db 100644 --- a/sinqEPICSApp/Db/el737Record.db +++ b/sinqEPICSApp/Db/el737Record.db @@ -11,6 +11,14 @@ record(stringin,"$(P):MsgTxt") { field(DTYP,"Soft Channel") } +record(longout,"$(P):ThresholdCounter") +{ + field(DTYP,"Soft Channel") +} +record(longout,"$(P):Threshold") +{ + field(DTYP,"Soft Channel") +} record(scaler,"$(P)") { field(DESC,"$(DESC)") diff --git a/sinqEPICSApp/src/devScalerEL737.c b/sinqEPICSApp/src/devScalerEL737.c index ca78a58..b4884bd 100644 --- a/sinqEPICSApp/src/devScalerEL737.c +++ b/sinqEPICSApp/src/devScalerEL737.c @@ -31,6 +31,12 @@ * to handle this. Moreover an external MsgTxt field in the DB can be filled with an error message. * * Mark Koennecke, July 2017 + * + * Enhanced with a separate thresholdCounter and threshold field in order to replace the + * hack for threshold handling. If these fields are present, the hack with presets 2 and + * 3 as described above is ignored. + * + * Mark Koennecke, August 2017 */ #include @@ -92,6 +98,7 @@ typedef struct { unsigned long values[NCOUNT]; unsigned int countCommand; unsigned int counting; + unsigned long thresholdValue; unsigned int sendThreshold; scalerRecord *psr; epicsEventId wakeUp; @@ -100,6 +107,8 @@ typedef struct { DBADDR pause; DBADDR status; DBADDR msgTxt; + DBADDR threshCounter; + DBADDR threshold; unsigned int dbInit; }EL737priv; @@ -145,6 +154,29 @@ static void connectSlaveRecords(EL737priv *priv) } else { errlogPrintf("dbNameToAddr succeded for %s, record access %s\n",slaveName, priv->status.precord->name); } + + snprintf(slaveName,sizeof(slaveName),"%s:ThresholdCounter", priv->psr->name); + errlogPrintf("Name of thresholdCounter variable: %s\n", slaveName); + status = dbNameToAddr(slaveName,&priv->threshCounter); + if(status!= 0){ + errSymLookup(status,errName,sizeof(errName)); + errlogPrintf("dbNameToAddr failed for %s with %s\n", slaveName, errName); + priv->dbInit = 0; + } else { + errlogPrintf("dbNameToAddr succeded for %s, record access %s\n",slaveName, priv->status.precord->name); + } + + snprintf(slaveName,sizeof(slaveName),"%s:Threshold", priv->psr->name); + errlogPrintf("Name of thresholdCounter variable: %s\n", slaveName); + status = dbNameToAddr(slaveName,&priv->threshold); + if(status!= 0){ + errSymLookup(status,errName,sizeof(errName)); + errlogPrintf("dbNameToAddr failed for %s with %s\n", slaveName, errName); + priv->dbInit = 0; + } else { + errlogPrintf("dbNameToAddr succeded for %s, record access %s\n",slaveName, priv->status.precord->name); + } + } static long el737_init_record(scalerRecord *psr, CALLBACK *pcallback) @@ -339,6 +371,12 @@ static asynStatus el737_transactCommand(EL737priv *priv,char command[COMLEN],cha strncpy(message,"Parameter missing",sizeof(message)); } else if(strstr(reply,"?6") != NULL){ strncpy(message,"to many counts",sizeof(message)); + } else if(strstr(reply,"?91") != NULL){ + strncpy(message,"Start Failure",sizeof(message)); + } else if(strstr(reply,"?92") != NULL){ + strncpy(message,"Failure while counting",sizeof(message)); + } else if(strstr(reply,"?93") != NULL){ + strncpy(message,"Read Failure",sizeof(message)); } else { if(strstr(reply,"?") != NULL) { snprintf(message,sizeof(message),"HW error: %s", reply); @@ -368,8 +406,43 @@ static asynStatus sendStop(EL737priv *priv) static void runEvents(EL737priv *priv) { - char command[COMLEN], reply[COMLEN]; + char command[COMLEN], reply[COMLEN], errName[256]; int status; + long dbStatus, myThreshold, nElements = 1, options = 0, threshCounter; + + /* + This is the better way to set the threshold rather then the old way below which uses + presets for that function. This one uses separate fields. + */ + if(priv->dbInit == 1) { + dbStatus = dbGetField(&priv->threshold,DBR_LONG,&myThreshold,&options, &nElements,NULL); + if(dbStatus != 0){ + errSymLookup(dbStatus,errName,sizeof(errName)); + errlogPrintf("Reading threshold failed with %s\n", errName); + } else { + if(myThreshold != priv->thresholdValue){ + /* + we have to set the threshold + */ + dbStatus = dbGetField(&priv->threshCounter,DBR_LONG,&threshCounter, &options, &nElements,NULL); + if(dbStatus != 0){ + errSymLookup(dbStatus,errName,sizeof(errName)); + errlogPrintf("Reading thresholdCounter failed with %s\n", errName); + } else { + sprintf(command,"DL %d %d", (int)threshCounter, + (int)myThreshold); + //errlogPrintf("Sending threshold command %s\n", command); + status = el737_transactCommand(priv,command,reply); + sprintf(command,"DR %d", (int)threshCounter); + status = el737_transactCommand(priv, command,reply); + if(status == asynSuccess){ + priv->sendThreshold = 0; + priv->thresholdValue = myThreshold; + } + } + } + } + } if(priv->sendThreshold == 1){ sprintf(command,"DL %d %d", (int)priv->presets[THRESHMON],