diff --git a/vmmTblApp/Db/vmm.template b/vmmTblApp/Db/vmm.template index f1d62272902de6ed74f44f7203451eebd5720a1e..0e9b641fdc1526eb3cc6755f91a4a3bb25cff2d2 100644 --- a/vmmTblApp/Db/vmm.template +++ b/vmmTblApp/Db/vmm.template @@ -60,4 +60,31 @@ record(ai, "$(P)$(R)$(HYB)$(VMM)$(C)ADCVal-R"){ field(PINI, "YES") field(SCAN, "I/O Intr") field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_$(VMM)_ADCVAL") + field(FLNK, "$(P)$(R)$(HYB)$(VMM)$(C)#ADCParams") +} + +record(fanout, "$(P)$(R)$(HYB)$(VMM)$(C)#ADCParams") { + field(LNK1, "$(P)$(R)$(HYB)$(VMM)$(C)Temp-R") + #Pulser... + #Bandgap... + #Threshold... +} + +# Is updated only when AnalogMon = 67 and ADCVal is read +record(ai, "$(P)$(R)$(HYB)$(VMM)$(C)Temp-R"){ + field(DESC, "Last read temperature") + field(DTYP, "asynFloat64") + field(PINI, "YES") + field(SCAN, "Passive") + field(FLNK, "$(P)$(R)$(HYB)$(VMM)$(C)TempTmstp-R") + field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_$(VMM)_TEMP") +} + +record(waveform, "$(P)$(R)$(HYB)$(VMM)$(C)TempTmstp-R") { + field(DESC, "Timestamp from last temperature read") + field(DTYP, "asynOctetRead") + field(NELM, "256") + field(FTVL, "CHAR") + field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_$(VMM)_TMP_TMSTP") + field(SCAN, "Passive") } \ No newline at end of file diff --git a/vmmTblApp/src/vmm_tbl.cpp b/vmmTblApp/src/vmm_tbl.cpp index 17cc41d234b76228f42fbf9949b52f1602e207a0..76fca14057727666c9331d9777d60ad3fd82d952 100644 --- a/vmmTblApp/src/vmm_tbl.cpp +++ b/vmmTblApp/src/vmm_tbl.cpp @@ -104,10 +104,49 @@ endOfReadInt32: return status; } +asynStatus VMMTbl::readFloat64(asynUser *pasynUser, epicsFloat64 *value) { + int function = pasynUser->reason; + asynStatus status = asynSuccess; + GenericParameter val; + vmmStatus result = vmmSuccess; + int param_index = 0, hyb_index, vmm_index; + + if (function < FIRST_VMM_PARAM) { + return asynPortDriver::readFloat64(pasynUser, value); + } + + // Search for parameter in adequate parameter vectors. If found, execute correct function for specific hybrid. + param_index = VecUtils::getIndex(vmmTemp_, function, hyb_index, vmm_index); + if (param_index >= 0) { + result = this->pVmmAPI->getTemperature(hyb_index, vmm_index, val); + *value = (epicsFloat64)val.value_float; + goto endOfReadFloat64; + } + +endOfReadFloat64: + if (param_index < 0) { + asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to find parameter %d.\n", driverName, __FUNCTION__, + function); + *value = 0; + return asynError; + } + if (result != vmmSuccess) { + asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to adequately read parameter: %d.\n", driverName, + __FUNCTION__, function); + status = asynError; + } + + setDoubleParam(function, *value); + callParamCallbacks(); + + return status; +} + asynStatus VMMTbl::readOctet(asynUser *pasynUser, char *value, size_t nChars, size_t *nActual, int *eomReason) { asynStatus status = asynSuccess; vmmStatus result; int function = pasynUser->reason; + int hyb_index, vmm_index; std::string read = ""; /* If this parameter belongs to a base class call its method */ @@ -134,6 +173,20 @@ asynStatus VMMTbl::readOctet(asynUser *pasynUser, char *value, size_t nChars, si goto endOfReadOctet; } + param_index = VecUtils::getIndex(vmmTempTmstp_, function, hyb_index, vmm_index); + if (param_index >= 0) { + GenericParameter val; + result = this->pVmmAPI->getTemperature(hyb_index, vmm_index, val); + + // Converting timestamp to string + std::time_t time_t_value = std::chrono::system_clock::to_time_t(val.timestamp); + std::tm tm_value = *std::localtime(&time_t_value); + std::ostringstream oss; + oss << std::put_time(&tm_value, "%Y-%m-%d %H:%M:%S"); + read = oss.str(); + goto endOfReadOctet; + } + endOfReadOctet: if (param_index < 0) { value[0] = '\0'; @@ -194,7 +247,7 @@ asynStatus VMMTbl::createEpicsParams() { createParamAndStoreInVector("HYB_" + std::to_string(hyb) + key, typ, vec); } - std::vector<int> SC, SL, ST, STH, SM, SD, SMX, ADCIDX, ADCVAL; + std::vector<int> SC, SL, ST, STH, SM, SD, SMX, ADCIDX, ADCVAL, TEMP, TEMPTMSTP; for (int vmm = 0; vmm < VMMS_PER_HYBRID; vmm++) { param_name.str(""); @@ -232,6 +285,14 @@ asynStatus VMMTbl::createEpicsParams() { param_name.str(""); param_name << "HYB_" << hyb << "_" << vmm << "_ADCVAL"; createParamAndStoreInVector(param_name.str(), asynParamInt32, &ADCVAL); + + param_name.str(""); + param_name << "HYB_" << hyb << "_" << vmm << "_TEMP"; + createParamAndStoreInVector(param_name.str(), asynParamFloat64, &TEMP); + + param_name.str(""); + param_name << "HYB_" << hyb << "_" << vmm << "_TMP_TMSTP"; + createParamAndStoreInVector(param_name.str(), asynParamOctet, &TEMPTMSTP); } this->vmmSC_.push_back(SC); @@ -243,6 +304,8 @@ asynStatus VMMTbl::createEpicsParams() { this->vmmSMX_.push_back(SMX); this->vmmADCIDX_.push_back(ADCIDX); this->vmmADCVAL_.push_back(ADCVAL); + this->vmmTemp_.push_back(TEMP); + this->vmmTempTmstp_.push_back(TEMPTMSTP); } return asynSuccess; diff --git a/vmmTblApp/src/vmm_tbl.h b/vmmTblApp/src/vmm_tbl.h index 2ee6df20dd856b85cb7afd15a49e519c5c9d247b..fa7c4682b04e1763c7444894c44e8da88600feee 100644 --- a/vmmTblApp/src/vmm_tbl.h +++ b/vmmTblApp/src/vmm_tbl.h @@ -22,6 +22,7 @@ class VMMTbl : public asynPortDriver { virtual asynStatus writeInt8Array(asynUser *pasynUser, epicsInt8 *value, size_t nElements); virtual asynStatus readInt8Array(asynUser *pasynUser, epicsInt8 *value, size_t nElements, size_t *nIn); virtual asynStatus readInt32(asynUser *pasynUser, epicsInt32 *value); + virtual asynStatus readFloat64(asynUser *pasynUser, epicsFloat64 *value); virtual asynStatus readOctet(asynUser *pasynUser, char *value, size_t maxChars, size_t *nActual, int *eomReason); asynStatus createParamAndStoreInVector(std::string paramName, asynParamType typ, std::vector<int> *vectorToStore); @@ -52,6 +53,8 @@ class VMMTbl : public asynPortDriver { std::vector<std::vector<int>> vmmSMX_; std::vector<std::vector<int>> vmmADCIDX_; std::vector<std::vector<int>> vmmADCVAL_; + std::vector<std::vector<int>> vmmTemp_; + std::vector<std::vector<int>> vmmTempTmstp_; private: static constexpr const char *driverName = "VMMTbl";