#include "vmm_tbl.h" /** Constructor for the VMMTbl class */ VMMTbl::VMMTbl(RMM *rmm, const char *FENPortName, int ring, int node, int hybrids) : asynPortDriver(FENPortName, 0, asynInt8ArrayMask | asynInt32Mask | asynInt64Mask | asynDrvUserMask | asynFloat64Mask | asynOctetMask, // Interfaces that we implement asynInt8ArrayMask | asynInt64Mask | asynInt32ArrayMask | asynFloat64Mask | asynInt32Mask | asynOctetMask, // Interfaces that do callbacks ASYN_MULTIDEVICE | ASYN_CANBLOCK, 1, /* ASYN_CANBLOCK=1, ASYN_MULTIDEVICE=1, autoConnect=1 */ 0, 0) { pVmmAPI = FrontEndFactory::createAndRegister<VMMAPI>(rmm->getRMMAPI(), ring, node, "VmmTbl", vmm_tbl_register_map, hybrids); createEpicsParams(); rmm->updateTopologyPvs(ring, node, "vmmTbl"); setStringParam(IOCMessage, "Finished starting IOC."); callParamCallbacks(); } asynStatus VMMTbl::readInt32(asynUser *pasynUser, epicsInt32 *value) { int function = pasynUser->reason; asynStatus status = asynSuccess; uint32_t val; int tmp_val; bool tmp_val_bool; uint8_t tmp_val_uint8; vmmStatus result = vmmSuccess; int param_index = 0, hyb_index, vmm_index; const char *paramName; getParamName(function, ¶mName); if (function < FIRST_VMM_PARAM) { return asynPortDriver::readInt32(pasynUser, value); } if (function == vmmAcquire_) { status = getIntegerParam(vmmAcquire_, value); goto endOfReadInt32; } if (function == vmmRegBankVersion) { result = this->pVmmAPI->getRegBankVersion(val); *value = val; goto endOfReadInt32; } if (function == vmmNumHybrids) { *value = this->pVmmAPI->getNumHybrids(true); goto endOfReadInt32; } if (function == vmmIsAcquiring_) { result = this->pVmmAPI->isAcquiring(tmp_val_bool); *value = tmp_val_bool; goto endOfReadInt32; } // Search for parameter in all parameter vectors. If found, execute correct function for specific hybrid. param_index = VecUtils::getIndex(vmmHybSkew_, function); if (param_index >= 0) { result = this->pVmmAPI->getSkew(param_index, tmp_val_uint8); *value = tmp_val_uint8; goto endOfReadInt32; } param_index = VecUtils::getIndex(vmmHybEnable_, function); if (param_index >= 0) { result = this->pVmmAPI->isHybridEnabled(param_index, tmp_val_bool); *value = tmp_val_bool; goto endOfReadInt32; } param_index = VecUtils::getIndex(vmmHybLinkStatus_, function); if (param_index >= 0) { result = this->pVmmAPI->checkLinkStatus(param_index, tmp_val); *value = tmp_val; goto endOfReadInt32; } param_index = VecUtils::getIndex(vmmHybWidth_, function); if (param_index >= 0) { result = this->pVmmAPI->getWidth(param_index, tmp_val_uint8); *value = tmp_val_uint8; goto endOfReadInt32; } param_index = VecUtils::getIndex(vmmHybPolarity_, function); if (param_index >= 0) { result = this->pVmmAPI->getHybPolarity(param_index, tmp_val_bool); *value = tmp_val_bool; goto endOfReadInt32; } param_index = VecUtils::getIndex(vmmADCIDX_, function, hyb_index, vmm_index); if (param_index == 0) { result = this->pVmmAPI->getADCIdx(hyb_index, vmm_index, tmp_val); *value = tmp_val; goto endOfReadInt32; } param_index = VecUtils::getIndex(vmmADCVAL_, function, hyb_index, vmm_index); if (param_index == 0) { result = this->pVmmAPI->readADC(hyb_index, vmm_index, tmp_val); *value = tmp_val; goto endOfReadInt32; } param_index = VecUtils::getIndex(vmmBdg_, function, hyb_index, vmm_index); if (param_index == 0) { GenericParameter param_value; result = this->pVmmAPI->getBandgap(hyb_index, vmm_index, param_value); *value = param_value.value_int; goto endOfReadInt32; } param_index = VecUtils::getIndex(vmmThr_, function, hyb_index, vmm_index); if (param_index == 0) { GenericParameter param_value; result = this->pVmmAPI->getThresholdADC(hyb_index, vmm_index, param_value); *value = param_value.value_int; goto endOfReadInt32; } param_index = VecUtils::getIndex(vmmPls_, function, hyb_index, vmm_index); if (param_index == 0) { GenericParameter param_value; result = this->pVmmAPI->getPulserADC(hyb_index, vmm_index, param_value); *value = param_value.value_int; goto endOfReadInt32; } endOfReadInt32: if (param_index < 0) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to find parameter %s, index: %d.\n", driverName, __FUNCTION__, paramName, function); std::string message = "Failed to find parameter: " + std::to_string(*paramName); setStringParam(IOCMessage, message.c_str()); *value = 0; return asynError; } if (result != vmmSuccess) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to adequately read parameter: %d.\n", driverName, __FUNCTION__, function); std::string message = "Failed to read parameter: " + std::to_string(*paramName); setStringParam(IOCMessage, message.c_str()); status = asynError; } setIntegerParam(function, *value); callParamCallbacks(); 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; const char *paramName; getParamName(function, ¶mName); 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); std::string message = "Failed to find parameter: " + std::to_string(*paramName); setStringParam(IOCMessage, message.c_str()); *value = 0; return asynError; } if (result != vmmSuccess) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to adequately read parameter: %d.\n", driverName, __FUNCTION__, function); std::string message = "Failed to read parameter: " + std::to_string(*paramName); setStringParam(IOCMessage, message.c_str()); 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 = ""; const char *paramName; getParamName(function, ¶mName); /* If this parameter belongs to a base class call its method */ if (function < FIRST_VMM_PARAM) { return asynPortDriver::readOctet(pasynUser, value, nChars, nActual, eomReason); } // Search for parameter in all parameter vectors. If found, execute correct function for specific hybrid. int param_index = VecUtils::getIndex(vmmHybFwVersion_, function); if (param_index >= 0) { result = this->pVmmAPI->readFwVersion(param_index, read); goto endOfReadOctet; } param_index = VecUtils::getIndex(vmmHybId_, function); if (param_index >= 0) { result = this->pVmmAPI->readIDChip(param_index, read); goto endOfReadOctet; } param_index = VecUtils::getIndex(vmmHybGeoPos_, function); if (param_index >= 0) { result = this->pVmmAPI->readGeoPos(param_index, read); 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); read = TimeUtils::timeToStr(val.timestamp); goto endOfReadOctet; } param_index = VecUtils::getIndex(vmmBdgTmstp_, function, hyb_index, vmm_index); if (param_index >= 0) { GenericParameter val; result = this->pVmmAPI->getBandgap(hyb_index, vmm_index, val); read = TimeUtils::timeToStr(val.timestamp); goto endOfReadOctet; } param_index = VecUtils::getIndex(vmmThrTmstp_, function, hyb_index, vmm_index); if (param_index >= 0) { GenericParameter val; result = this->pVmmAPI->getThresholdADC(hyb_index, vmm_index, val); read = TimeUtils::timeToStr(val.timestamp); goto endOfReadOctet; } param_index = VecUtils::getIndex(vmmPlsTmstp_, function, hyb_index, vmm_index); if (param_index >= 0) { GenericParameter val; result = this->pVmmAPI->getPulserADC(hyb_index, vmm_index, val); read = TimeUtils::timeToStr(val.timestamp); goto endOfReadOctet; } endOfReadOctet: if (param_index < 0) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to find parameter %s, index: %d.\n", driverName, __FUNCTION__, paramName, function); std::string message = "Failed to find parameter: " + std::to_string(*paramName); setStringParam(IOCMessage, message.c_str()); value[0] = '\0'; *nActual = 1; return asynError; } if (result != vmmSuccess) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to adequately read parameter: %s, index: %d.\n", driverName, __FUNCTION__, paramName, function); std::string message = "Failed to read parameter: " + std::to_string(*paramName); setStringParam(IOCMessage, message.c_str()); status = asynError; } size_t copy_size = std::min(read.size(), nChars); strncpy(value, read.c_str(), copy_size); setStringParam(function, value); value[copy_size] = '\0'; *nActual = copy_size; *eomReason = ASYN_EOM_END; callParamCallbacks(); return status; } asynStatus VMMTbl::createParamAndStoreInVector(std::string paramName, asynParamType typ, std::vector<int> *vectorToStore) { int paramIndex; asynStatus status = createParam(paramName.c_str(), typ, ¶mIndex); if (status != asynSuccess) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to create parameter %s.\n", driverName, __FUNCTION__, paramName.c_str()); return asynError; } vectorToStore->push_back(paramIndex); return asynSuccess; } asynStatus VMMTbl::createEpicsParams() { createParam("REG_BANK_VERSION", asynParamInt32, &vmmRegBankVersion); createParam("VMM_FEN_ACQUIRE", asynParamInt32, &vmmAcquire_); createParam("VMM_FEN_ACQUIRING", asynParamInt32, &vmmIsAcquiring_); createParam("NUM_HYBRIDS", asynParamInt32, &vmmNumHybrids); createParam("IOC_MESSAGE", asynParamOctet, &IOCMessage); std::tuple<std::string, asynParamType, std::vector<int> *> hyb_params_to_create[8] = { {"_FW_VERSION", asynParamOctet, &vmmHybFwVersion_}, {"_ID", asynParamOctet, &vmmHybId_}, {"_GEOPOS", asynParamOctet, &vmmHybGeoPos_}, {"_LINK_STATUS", asynParamInt32, &vmmHybLinkStatus_}, {"_SKEW", asynParamInt32, &vmmHybSkew_}, {"_WIDTH", asynParamInt32, &vmmHybWidth_}, {"_ENABLE", asynParamInt32, &vmmHybEnable_}, {"_POLARITY", asynParamInt32, &vmmHybPolarity_}}; std::ostringstream param_name; for (int hyb = 0; hyb < this->pVmmAPI->getNumHybrids(); hyb++) { for (const auto &hyb_param : hyb_params_to_create) { const std::string &key = std::get<0>(hyb_param); asynParamType typ = std::get<1>(hyb_param); std::vector<int> *vec = std::get<2>(hyb_param); createParamAndStoreInVector("HYB_" + std::to_string(hyb) + key, typ, vec); } std::vector<int> SC, SL, ST, STH, SM, SD, SMX, ADCIDX, ADCVAL; std::vector<int> TEMP, TEMPTMSTP, BDG, BDGTMPSTP, THR, THRTMPSTP, PLS, PLSTMPSTP; for (int vmm = 0; vmm < VMMS_PER_HYBRID; vmm++) { param_name.str(""); param_name << "HYB_" << hyb << "_" << vmm << "_SC"; createParamAndStoreInVector(param_name.str(), asynParamInt8Array, &SC); param_name.str(""); param_name << "HYB_" << hyb << "_" << vmm << "_SL"; createParamAndStoreInVector(param_name.str(), asynParamInt8Array, &SL); param_name.str(""); param_name << "HYB_" << hyb << "_" << vmm << "_ST"; createParamAndStoreInVector(param_name.str(), asynParamInt8Array, &ST); param_name.str(""); param_name << "HYB_" << hyb << "_" << vmm << "_STH"; createParamAndStoreInVector(param_name.str(), asynParamInt8Array, &STH); param_name.str(""); param_name << "HYB_" << hyb << "_" << vmm << "_SM"; createParamAndStoreInVector(param_name.str(), asynParamInt8Array, &SM); param_name.str(""); param_name << "HYB_" << hyb << "_" << vmm << "_SD"; createParamAndStoreInVector(param_name.str(), asynParamInt8Array, &SD); param_name.str(""); param_name << "HYB_" << hyb << "_" << vmm << "_SMX"; createParamAndStoreInVector(param_name.str(), asynParamInt8Array, &SMX); param_name.str(""); param_name << "HYB_" << hyb << "_" << vmm << "_ANALOGMON"; createParamAndStoreInVector(param_name.str(), asynParamInt32, &ADCIDX); 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); param_name.str(""); param_name << "HYB_" << hyb << "_" << vmm << "_BDG"; createParamAndStoreInVector(param_name.str(), asynParamInt32, &BDG); param_name.str(""); param_name << "HYB_" << hyb << "_" << vmm << "_BDG_TMSTP"; createParamAndStoreInVector(param_name.str(), asynParamOctet, &BDGTMPSTP); param_name.str(""); param_name << "HYB_" << hyb << "_" << vmm << "_THR"; createParamAndStoreInVector(param_name.str(), asynParamInt32, &THR); param_name.str(""); param_name << "HYB_" << hyb << "_" << vmm << "_THR_TMSTP"; createParamAndStoreInVector(param_name.str(), asynParamOctet, &THRTMPSTP); param_name.str(""); param_name << "HYB_" << hyb << "_" << vmm << "_PLS"; createParamAndStoreInVector(param_name.str(), asynParamInt32, &PLS); param_name.str(""); param_name << "HYB_" << hyb << "_" << vmm << "_PLS_TMSTP"; createParamAndStoreInVector(param_name.str(), asynParamOctet, &PLSTMPSTP); } this->vmmSC_.push_back(SC); this->vmmSL_.push_back(SL); this->vmmST_.push_back(ST); this->vmmSTH_.push_back(STH); this->vmmSM_.push_back(SM); this->vmmSD_.push_back(SD); 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); this->vmmBdg_.push_back(BDG); this->vmmBdgTmstp_.push_back(BDGTMPSTP); this->vmmThr_.push_back(THR); this->vmmThrTmstp_.push_back(THRTMPSTP); this->vmmPls_.push_back(PLS); this->vmmPlsTmstp_.push_back(PLSTMPSTP); } return asynSuccess; } asynStatus VMMTbl::writeInt32(asynUser *pasynUser, epicsInt32 value) { asynStatus status = asynSuccess; vmmStatus vmm_stat = vmmSuccess; bool is_acquiring; int function = pasynUser->reason; int param_index = 0, hyb_index, vmm_index; const char *paramName; getParamName(function, ¶mName); if (function < FIRST_VMM_PARAM) { return asynPortDriver::writeInt32(pasynUser, value); } if (function == vmmAcquire_) { setStringParam(IOCMessage, std::string("Set acquire to " + std::to_string(value)).c_str()); vmm_stat = this->pVmmAPI->isAcquiring(is_acquiring); if (is_acquiring == (bool)value) { setStringParam(IOCMessage, "Error: Set to acquire/stop but already acquiring/stopped."); status = asynError; } else { this->pVmmAPI->acquire((bool)value); } goto endOfWriteInt32; } // Search for parameter in all parameter vectors. If found, execute correct function for specific hybrid. param_index = VecUtils::getIndex(vmmHybSkew_, function); if (param_index >= 0) { setStringParam( IOCMessage, std::string("Set skew from hybrid " + std::to_string(param_index) + " to " + std::to_string(value)).c_str()); vmm_stat = this->pVmmAPI->setSkew(param_index, value); goto endOfWriteInt32; } param_index = VecUtils::getIndex(vmmHybEnable_, function); if (param_index >= 0) { setStringParam(IOCMessage, std::string("Setting enable/disable for hybrid " + std::to_string(param_index) + " to " + std::to_string(value)) .c_str()); vmm_stat = this->pVmmAPI->enableHybrid(param_index, (bool)value); goto endOfWriteInt32; } param_index = VecUtils::getIndex(vmmHybWidth_, function); if (param_index >= 0) { setStringParam( IOCMessage, std::string("Set width from hybrid " + std::to_string(param_index) + " to " + std::to_string(value)).c_str()); vmm_stat = this->pVmmAPI->setWidth(param_index, value); goto endOfWriteInt32; } param_index = VecUtils::getIndex(vmmHybPolarity_, function); if (param_index >= 0) { setStringParam(IOCMessage, std::string("Set polarity from hybrid " + std::to_string(param_index) + " to " + std::to_string(value)) .c_str()); vmm_stat = this->pVmmAPI->setHybPolarity(param_index, value); goto endOfWriteInt32; } param_index = VecUtils::getIndex(vmmADCIDX_, function, hyb_index, vmm_index); if (param_index == 0) { setStringParam(IOCMessage, std::string("Set ADC index of hybrid " + std::to_string(hyb_index) + ", vmm " + std::to_string(vmm_index) + " to " + std::to_string(value)) .c_str()); vmm_stat = this->pVmmAPI->setADCIdx(hyb_index, vmm_index, value); goto endOfWriteInt32; } endOfWriteInt32: if (param_index < 0) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to find parameter %s, index: %d.\n", driverName, __FUNCTION__, paramName, function); std::string message = "Failed to find parameter: " + std::to_string(*paramName); setStringParam(IOCMessage, message.c_str()); status = asynError; } if (vmm_stat != vmmSuccess) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to write to parameter %s, index: %d.\n", driverName, __FUNCTION__, paramName, function); std::string message = "Failed to write to parameter: " + std::to_string(*paramName); setStringParam(IOCMessage, message.c_str()); status = asynError; } setIntegerParam(function, value); callParamCallbacks(); return status; } asynStatus VMMTbl::readInt8Array(asynUser *pasynUser, epicsInt8 *value, size_t nElements, size_t *nIn) { int function, hyb_index, vmm_index, found_param = -10, status = 0; uint8_t data_int; bool data; const char *paramName; function = pasynUser->reason; getParamName(function, ¶mName); if (function < FIRST_VMM_PARAM) return asynPortDriver::readInt8Array(pasynUser, value, nElements, nIn); found_param = VecUtils::getIndex(vmmSC_, function, hyb_index, vmm_index); if (found_param == 0) { for (size_t i = 0; i < nElements; i++) { status |= (int)this->pVmmAPI->getSC(hyb_index, vmm_index, i, data); value[i] = data; } goto endOfReadInt8Array; } found_param = VecUtils::getIndex(vmmSL_, function, hyb_index, vmm_index); if (found_param == 0) { for (size_t i = 0; i < nElements; i++) { status |= (int)this->pVmmAPI->getSL(hyb_index, vmm_index, i, data); value[i] = data; } goto endOfReadInt8Array; } found_param = VecUtils::getIndex(vmmST_, function, hyb_index, vmm_index); if (found_param == 0) { for (size_t i = 0; i < nElements; i++) { status |= (int)this->pVmmAPI->getST(hyb_index, vmm_index, i, data); value[i] = data; } goto endOfReadInt8Array; } found_param = VecUtils::getIndex(vmmSTH_, function, hyb_index, vmm_index); if (found_param == 0) { for (size_t i = 0; i < nElements; i++) { status |= (int)this->pVmmAPI->getSTH(hyb_index, vmm_index, i, data); value[i] = data; } goto endOfReadInt8Array; } found_param = VecUtils::getIndex(vmmSM_, function, hyb_index, vmm_index); if (found_param == 0) { for (size_t i = 0; i < nElements; i++) { status |= (int)this->pVmmAPI->getSM(hyb_index, vmm_index, i, data); value[i] = data; } goto endOfReadInt8Array; } found_param = VecUtils::getIndex(vmmSD_, function, hyb_index, vmm_index); if (found_param == 0) { for (size_t i = 0; i < nElements; i++) { status |= (int)this->pVmmAPI->getSD(hyb_index, vmm_index, i, data_int); value[i] = data_int; } goto endOfReadInt8Array; } found_param = VecUtils::getIndex(vmmSMX_, function, hyb_index, vmm_index); if (found_param == 0) { for (size_t i = 0; i < nElements; i++) { status |= (int)this->pVmmAPI->getSMX(hyb_index, vmm_index, i, data); value[i] = data; } goto endOfReadInt8Array; } endOfReadInt8Array: if (found_param != 0) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to find parameter %s, index %d.\n", driverName, __FUNCTION__, paramName, function); std::string message = "Failed to find parameter: " + std::to_string(*paramName); setStringParam(IOCMessage, message.c_str()); *nIn = 0; return asynError; } *nIn = nElements; status |= (int)doCallbacksInt8Array(value, nElements, function, 0); if (status) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to get paramter %s, index %d.\n", driverName, __FUNCTION__, paramName, function); std::string message = "Failed to read parameter: " + std::to_string(*paramName); setStringParam(IOCMessage, message.c_str()); return asynError; } return asynSuccess; } asynStatus VMMTbl::writeInt8Array(asynUser *pasynUser, epicsInt8 *value, size_t nElements) { int function, hyb_index, vmm_index, status = 0, found_param = -10; const char *paramName; function = pasynUser->reason; getParamName(function, ¶mName); if (function < FIRST_VMM_PARAM) return asynPortDriver::writeInt8Array(pasynUser, value, nElements); found_param = VecUtils::getIndex(vmmSC_, function, hyb_index, vmm_index); if (found_param == 0) { for (size_t i = 0; i < nElements; i++) { status |= (int)this->pVmmAPI->setSC(hyb_index, vmm_index, i, (bool)value[i]); } goto endOfWriteInt8Array; } found_param = VecUtils::getIndex(vmmSL_, function, hyb_index, vmm_index); if (found_param == 0) { for (size_t i = 0; i < nElements; i++) { status |= (int)this->pVmmAPI->setSL(hyb_index, vmm_index, i, (bool)value[i]); } goto endOfWriteInt8Array; } found_param = VecUtils::getIndex(vmmST_, function, hyb_index, vmm_index); if (found_param == 0) { for (size_t i = 0; i < nElements; i++) { status |= (int)this->pVmmAPI->setST(hyb_index, vmm_index, i, (bool)value[i]); } goto endOfWriteInt8Array; } found_param = VecUtils::getIndex(vmmSTH_, function, hyb_index, vmm_index); if (found_param == 0) { for (size_t i = 0; i < nElements; i++) { status |= (int)this->pVmmAPI->setSTH(hyb_index, vmm_index, i, (bool)value[i]); } goto endOfWriteInt8Array; } found_param = VecUtils::getIndex(vmmSM_, function, hyb_index, vmm_index); if (found_param == 0) { for (size_t i = 0; i < nElements; i++) { status |= (int)this->pVmmAPI->setSM(hyb_index, vmm_index, i, (bool)value[i]); } goto endOfWriteInt8Array; } found_param = VecUtils::getIndex(vmmSMX_, function, hyb_index, vmm_index); if (found_param == 0) { for (size_t i = 0; i < nElements; i++) { status |= (int)this->pVmmAPI->setSMX(hyb_index, vmm_index, i, (bool)value[i]); } goto endOfWriteInt8Array; } found_param = VecUtils::getIndex(vmmSD_, function, hyb_index, vmm_index); if (found_param == 0) { for (size_t i = 0; i < nElements; i++) { status |= (int)this->pVmmAPI->setSD(hyb_index, vmm_index, i, value[i]); } goto endOfWriteInt8Array; } endOfWriteInt8Array: status |= (int)doCallbacksInt8Array(value, nElements, function, 0); // Comparing different statuses, yes. if (found_param != 0) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to find parameter %s, index %d.\n", driverName, __FUNCTION__, paramName, function); std::string message = "Failed to find parameter: " + std::to_string(*paramName); setStringParam(IOCMessage, message.c_str()); return asynError; } if (status) { asynPrint(pasynUserSelf, ASYN_TRACE_ERROR, "%s:%s: Failed to set paramter %s.\n", driverName, __FUNCTION__, paramName); std::string message = "Failed to write to parameter: " + std::to_string(*paramName); setStringParam(IOCMessage, message.c_str()); return asynError; } return asynSuccess; } extern "C" { static void VMMTblConfig(const char *RMMPortName, const char *FENPortName, int ring, int hybrids) { int node = 0; // VMM use always only the Node 0 RMM *pRMM; pRMM = (RMM *)findAsynPortDriver(RMMPortName); if (pRMM != nullptr) { new VMMTbl(pRMM, FENPortName, ring, node, hybrids); } else { std::cerr << "Error: Failed to find RMM for port " << RMMPortName << std::endl; } } static const iocshArg configArg0 = {"RMM Port name", iocshArgString}; static const iocshArg configArg1 = {"Front End Port Name", iocshArgString}; static const iocshArg configArg2 = {"Ring", iocshArgInt}; static const iocshArg configArg3 = {"Hybrids", iocshArgInt}; static const iocshArg *const configArgs[] = {&configArg0, &configArg1, &configArg2, &configArg3}; static const iocshFuncDef configFuncDef = {"VMMTblConfig", 4, configArgs}; static void configCallFunc(const iocshArgBuf *args) { VMMTblConfig(args[0].sval, args[1].sval, args[2].ival, args[3].ival); } static void VMMTblRegister(void) { iocshRegister(&configFuncDef, configCallFunc); } epicsExportRegistrar(VMMTblRegister); } // end extern "C"