Skip to content
Snippets Groups Projects
Commit 9fcb1f57 authored by Marco Filho's avatar Marco Filho
Browse files

MAJOR REFACTOR

This commit was done with an inescrupulous "git add ." after several
radical modifications.

Anyway, the API was radically modified and basically the old way the
code worked does not make any sense anymore.

The desired architecture is the following: the API is going to be used
as a class component. Each parameter will be created according to the
desired number of enabled hybrids.

Each parameter should use one simple API function. No information about
the VMM or hybrids itself is stored in the VMMTbl class unless extremely
needed.

This commit leaves a few old parameters that should be removed in the
future such as ADC_VALUE_VMM1, READ_ADC_VMMS, etc. This is only to serve
as a reminder to add those later.
parent ebd63cb8
No related branches found
No related tags found
1 merge request!7Major refactor
...@@ -14,6 +14,7 @@ SUBS = $(APPDB)/channels.sub ...@@ -14,6 +14,7 @@ SUBS = $(APPDB)/channels.sub
LIB_SYS_LIBS += vmmapi LIB_SYS_LIBS += vmmapi
SOURCES += $(APPSRC)/vmm_tbl.cpp SOURCES += $(APPSRC)/vmm_tbl.cpp
SOURCES += $(APPSRC)/Utils.cpp
DBDS += $(APPSRC)/vmm_tbl.dbd DBDS += $(APPSRC)/vmm_tbl.dbd
......
...@@ -9,9 +9,19 @@ record(aao, "$(P)$(R)$(HYB)$(VMM)$(C)$(CH)-S") { ...@@ -9,9 +9,19 @@ record(aao, "$(P)$(R)$(HYB)$(VMM)$(C)$(CH)-S") {
field(DTYP, "asynInt8ArrayOut") field(DTYP, "asynInt8ArrayOut")
field(NELM, "64") field(NELM, "64")
field(FTVL, "CHAR") field(FTVL, "CHAR")
field(FLNK, "$(P)$(R)$(HYB)$(VMM)$(C)$(CH)-R")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_$(VMM)_$(CH)") field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_$(VMM)_$(CH)")
} }
record(aai, "$(P)$(R)$(HYB)$(VMM)$(C)$(CH)-R") {
field(DESC, "Get $(CH) channels array")
field(DTYP, "asynInt8ArrayIn")
field(NELM, "64")
field(FTVL, "CHAR")
field(SCAN, "I/O Intr")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_$(VMM)_$(CH)")
}
record(bo, "$(P)$(R)$(HYB)$(VMM)$(C)All$(CH)-S") { record(bo, "$(P)$(R)$(HYB)$(VMM)$(C)All$(CH)-S") {
field(DESC, "Set all $(CH) channels") field(DESC, "Set all $(CH) channels")
field(VAL, "0") field(VAL, "0")
......
...@@ -2,12 +2,160 @@ record(stringin, "$(P)$(R)Hyb$(HYB)FwVersion-R") { ...@@ -2,12 +2,160 @@ record(stringin, "$(P)$(R)Hyb$(HYB)FwVersion-R") {
field(DESC, "Hybrid $(HYB) Firmware version") field(DESC, "Hybrid $(HYB) Firmware version")
field(DTYP, "asynOctetRead") field(DTYP, "asynOctetRead")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_FW_VERSION") field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_FW_VERSION")
field(PINI, "YES")
field(SCAN, "I/O Intr") field(SCAN, "I/O Intr")
} }
record(mbbo, "$(P)$(R)Hyb$(HYB)Skew-S"){
field(DESC, "Hybrid's #$(HYB) Skew")
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_SKEW")
field(ZRST, "0 ns")
field(ZRVL, "0")
field(ONST, "2.83921 ns")
field(ONVL, "1")
field(TWST, "5.67842 ns")
field(TWVL, "2")
field(THST, "8.51764 ns")
field(THVL, "3")
field(FRST, "11.3568 ns")
field(FRVL, "4")
field(FVST, "14.1961 ns")
field(FVVL, "5")
field(SXST, "17.0353 ns")
field(SXVL, "6")
field(SVST, "19.8545 ns")
field(SVVL, "7")
field(EIST, "22.7137 ns")
field(EIVL, "8")
field(NIST, "25.5529 ns")
field(NIVL, "9")
field(TEST, "28.3921 ns")
field(TEVL, "10")
field(ELST, "31.2313 ns")
field(ELVL, "11")
field(TVST, "34.0705 ns")
field(TVVL, "12")
field(TTST, "36.9098 ns")
field(TTVL, "13")
field(FTST, "39.749 ns")
field(FTVL, "14")
field(FFST, "42.5882 ns")
field(FFVL, "15")
field(FLNK, "$(P)$(R)Hyb$(HYB)Skew-RB")
}
record(mbbi, "$(P)$(R)Hyb$(HYB)Skew-RB"){
field(DESC, "Hybrid's #$(HYB) Skew")
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_SKEW")
field(ZRST, "0 ns")
field(ZRVL, "0")
field(ONST, "2.83921 ns")
field(ONVL, "1")
field(TWST, "5.67842 ns")
field(TWVL, "2")
field(THST, "8.51764 ns")
field(THVL, "3")
field(FRST, "11.3568 ns")
field(FRVL, "4")
field(FVST, "14.1961 ns")
field(FVVL, "5")
field(SXST, "17.0353 ns")
field(SXVL, "6")
field(SVST, "19.8545 ns")
field(SVVL, "7")
field(EIST, "22.7137 ns")
field(EIVL, "8")
field(NIST, "25.5529 ns")
field(NIVL, "9")
field(TEST, "28.3921 ns")
field(TEVL, "10")
field(ELST, "31.2313 ns")
field(ELVL, "11")
field(TVST, "34.0705 ns")
field(TVVL, "12")
field(TTST, "36.9098 ns")
field(TTVL, "13")
field(FTST, "39.749 ns")
field(FTVL, "14")
field(FFST, "42.5882 ns")
field(FFVL, "15")
field(SCAN, "I/O Intr")
field(PINI, "YES")
}
record(mbbo, "$(P)$(R)Hyb$(HYB)Width-S"){
field(DESC, "Hybrid's #$(HYB) Width")
field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_WIDTH")
field(ZRST, "128 x 22.7137")
field(ZRVL, "0")
field(ONST, "64 x 22.7137")
field(ONVL, "1")
field(TWST, "32 x 22.7137")
field(TWVL, "2")
field(THST, "16 x 22.7137")
field(THVL, "3")
field(FRST, "8 x 22.7137")
field(FRVL, "4")
field(FVST, "4 x 22.7137")
field(FVVL, "5")
field(SXST, "2 x 22.7137")
field(SXVL, "6")
field(SVST, "1 x 22.7137")
field(SVVL, "7")
field(FLNK, "$(P)$(R)Hyb$(HYB)Width-RB")
}
record(mbbi, "$(P)$(R)Hyb$(HYB)Width-RB"){
field(DESC, "Hybrid's #$(HYB) Width")
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_WIDTH")
field(PINI, "YES")
field(ZRST, "128 x 22.7137")
field(ZRVL, "0")
field(ONST, "64 x 22.7137")
field(ONVL, "1")
field(TWST, "32 x 22.7137")
field(TWVL, "2")
field(THST, "16 x 22.7137")
field(THVL, "3")
field(FRST, "8 x 22.7137")
field(FRVL, "4")
field(FVST, "4 x 22.7137")
field(FVVL, "5")
field(SXST, "2 x 22.7137")
field(SXVL, "6")
field(SVST, "1 x 22.7137")
field(SVVL, "7")
field(SCAN, "I/O Intr")
}
record(bo, "$(P)$(R)Hyb$(HYB)Pol-S") {
field(DESC, "Hybrid's #$(HYB) Polarity")
field(DTYP, "asynInt32")
field(VAL, "0")
field(ZNAM, "positive")
field(ONAM, "negative")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_POLARITY")
}
record(bi, "$(P)$(R)Hyb$(HYB)Pol-RB") {
field(DESC, "Hybrid's #$(HYB) Polarity")
field(DTYP, "asynInt32")
field(VAL, "0")
field(ZNAM, "positive")
field(ONAM, "negative")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_POLARITY")
field(SCAN, "I/O Intr")
field(PINI, "YES")
}
record(stringin, "$(P)$(R)Hyb$(HYB)ID-R") { record(stringin, "$(P)$(R)Hyb$(HYB)ID-R") {
field(DESC, "Hybrid $(HYB) ID") field(DESC, "Hybrid $(HYB) ID")
field(DTYP, "asynOctetRead") field(DTYP, "asynOctetRead")
field(PINI, "YES")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_ID") field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_ID")
field(SCAN, "I/O Intr") field(SCAN, "I/O Intr")
} }
...@@ -15,12 +163,15 @@ record(stringin, "$(P)$(R)Hyb$(HYB)ID-R") { ...@@ -15,12 +163,15 @@ record(stringin, "$(P)$(R)Hyb$(HYB)ID-R") {
record(stringin, "$(P)$(R)Hyb$(HYB)GeoPos-R") { record(stringin, "$(P)$(R)Hyb$(HYB)GeoPos-R") {
field(DESC, "Hybrid $(HYB) Geo Position") field(DESC, "Hybrid $(HYB) Geo Position")
field(DTYP, "asynOctetRead") field(DTYP, "asynOctetRead")
field(PINI, "YES")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_GEOPOS") field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_GEOPOS")
field(SCAN, "I/O Intr") field(SCAN, "I/O Intr")
} }
record(mbbi, "$(P)$(R)Hyb$(HYB)LinkStatus-R") { record(mbbi, "$(P)$(R)Hyb$(HYB)LinkStatus-R") {
field(DESC, "Hybrid $(HYB) Link Status") field(DESC, "Hybrid $(HYB) Link Status")
field(PINI, "YES")
field(DTYP, "asynInt32")
field(ZRST, "not connected") field(ZRST, "not connected")
field(ZRVL, "0") field(ZRVL, "0")
field(ONST, "start alignment") field(ONST, "start alignment")
...@@ -34,6 +185,5 @@ record(mbbi, "$(P)$(R)Hyb$(HYB)LinkStatus-R") { ...@@ -34,6 +185,5 @@ record(mbbi, "$(P)$(R)Hyb$(HYB)LinkStatus-R") {
field(FVST, "acq") field(FVST, "acq")
field(FVVL, "5") field(FVVL, "5")
field(SCAN, "I/O Intr") field(SCAN, "I/O Intr")
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_LINK_STATUS") field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))HYB_$(HYB)_LINK_STATUS")
} }
...@@ -56,3 +56,11 @@ record(bo, "$(P)$(R)Acquire-S") { ...@@ -56,3 +56,11 @@ record(bo, "$(P)$(R)Acquire-S") {
field(DTYP, "asynInt32") field(DTYP, "asynInt32")
field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))VMM_FEN_ACQUIRE") field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))VMM_FEN_ACQUIRE")
} }
record(ai, "$(P)$(R)RegBankVersion-R"){
field(DESC, "Register bank version")
field(PINI, "YES")
field(DTYP, "asynInt32")
field(INP, "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))REG_BANK_VERSION")
field(SCAN, "I/O Intr")
}
\ No newline at end of file
#include <bits/stdc++.h>
#include "Utils.h"
/**
* @brief Gets index of number in vector.
* @param vec Vector to find number in
* @param function number to find.
* @return -1 if number is not found. -2 if number is repeated. Index of element if number is found.
**/
int VecUtils::getIndex(std::vector<int>& vec, int function){
int c = std::count(vec.begin(), vec.end(), function);
if (c == 0) return -1;
if (c > 1) return -2;
auto it = std::find(vec.begin(), vec.end(), function);
if (it != vec.end()) return std::distance(vec.begin(), it);
return -1;
}
/**
* @brief Gets two indexes of number in vector<vector<int>>.
* @param vec Vector to find number in
* @param function number to find.
* @param hyb_index reference to put the hybrid index in.
* @param vmm_index reference to put the vmm index in.
* @return -1 if number is not found. -2 if number is repeated. 0 if number is found.
**/
int VecUtils::getIndex(std::vector<std::vector<int>>& vec, int function, int &hyb_index, int &vmm_index) {
hyb_index = -1;
vmm_index = -1;
int occurrences = 0;
for (size_t i = 0; i < vec.size(); ++i) {
auto& subvec = vec[i];
auto it = std::find(subvec.begin(), subvec.end(), function);
if (it != subvec.end()) {
++occurrences;
if (occurrences > 1) {
hyb_index = -2;
vmm_index = -2;
return -2; // Duplicated
}
hyb_index = static_cast<int>(i);
vmm_index = static_cast<int>(std::distance(subvec.begin(), it));
}
}
if (occurrences == 0) {
hyb_index = -1;
vmm_index = -1;
return -1; // Not found
}
return 0; // Found exactly once
}
\ No newline at end of file
// Generic utilities for the module
#include <vector>
namespace VecUtils{
int getIndex(std::vector<int>&, int function);
int getIndex(std::vector<std::vector<int>>&, int function, int &hyb_index, int &vmm_index);
}
\ No newline at end of file
...@@ -6,8 +6,7 @@ VMMTbl::VMMTbl(RMM* rmm, const char *FENPortName, int ring, int node, int hybrid ...@@ -6,8 +6,7 @@ VMMTbl::VMMTbl(RMM* rmm, const char *FENPortName, int ring, int node, int hybrid
asynInt8ArrayMask | asynInt32Mask | asynInt64Mask | asynDrvUserMask | asynFloat64Mask | asynOctetMask, // Interfaces that we implement asynInt8ArrayMask | asynInt32Mask | asynInt64Mask | asynDrvUserMask | asynFloat64Mask | asynOctetMask, // Interfaces that we implement
asynInt8ArrayMask | asynInt64Mask | asynInt32ArrayMask | asynFloat64Mask | asynInt32Mask | asynOctetMask, // Interfaces that do callbacks asynInt8ArrayMask | asynInt64Mask | asynInt32ArrayMask | asynFloat64Mask | asynInt32Mask | asynOctetMask, // Interfaces that do callbacks
ASYN_MULTIDEVICE | ASYN_CANBLOCK, 1, /* ASYN_CANBLOCK=1, ASYN_MULTIDEVICE=1, autoConnect=1 */ ASYN_MULTIDEVICE | ASYN_CANBLOCK, 1, /* ASYN_CANBLOCK=1, ASYN_MULTIDEVICE=1, autoConnect=1 */
0, 0), 0, 0)
number_hybrids(hybrids)
{ {
pVmmAPI = FrontEndFactory::createAndRegister<VMMAPI>( pVmmAPI = FrontEndFactory::createAndRegister<VMMAPI>(
...@@ -15,183 +14,346 @@ VMMTbl::VMMTbl(RMM* rmm, const char *FENPortName, int ring, int node, int hybrid ...@@ -15,183 +14,346 @@ VMMTbl::VMMTbl(RMM* rmm, const char *FENPortName, int ring, int node, int hybrid
ring, ring,
node, node,
"VmmTbl", "VmmTbl",
vmm_tbl_register_map); vmm_tbl_register_map,
hybrids);
createEpicsParams(); createEpicsParams();
setInitialEpicsParams();
rmm->updateTopologyPvs(ring, node, "vmmTbl"); rmm->updateTopologyPvs(ring, node, "vmmTbl");
if (rmm->getRMMAPI()->checkRings() == rmmSuccess) {
for (int hyb = 0; hyb < number_hybrids; hyb++) { }
pVmmAPI->enableHybrid(hyb, true);
setStringParam(vmmHybFwVersion_[hyb], pVmmAPI->readFwVersion(hyb).c_str()); asynStatus VMMTbl::readInt32(asynUser *pasynUser, epicsInt32 *value) {
setStringParam(vmmHybId_[hyb], pVmmAPI->readIDChip(hyb).c_str()); int function = pasynUser->reason;
setStringParam(vmmHybGeoPos_[hyb], pVmmAPI->readGeoPos(hyb).c_str()); asynStatus status = asynSuccess;
setIntegerParam(vmmHybLinkStatus_[hyb], std::stoi(pVmmAPI->checkLinkStatus(hyb))); uint32_t val;
int tmp_val;
bool tmp_val_bool;
uint8_t tmp_val_uint8;
int param_index;
if (function < FIRST_VMM_PARAM) {
return asynPortDriver::readInt32(pasynUser, value);
}
if (function == vmmRegBankVersion) {
vmmStatus result = this->pVmmAPI->getRegBankVersion(val);
if (result != vmmSuccess) status = asynError;
*value = val;
param_index = 10000; /// \todo So endOfReadInt32 won't return asynError; Maybe improve mechanism?
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) {
this->pVmmAPI->getSkew(param_index, tmp_val_uint8);
*value = tmp_val_uint8;
goto endOfReadInt32;
}
param_index = VecUtils::getIndex(vmmHybLinkStatus_, function);
if (param_index >= 0) {
this->pVmmAPI->checkLinkStatus(param_index, tmp_val);
*value = tmp_val;
goto endOfReadInt32;
}
param_index = VecUtils::getIndex(vmmHybWidth_, function);
if (param_index >= 0) {
this->pVmmAPI->getWidth(param_index, tmp_val_uint8);
*value = tmp_val_uint8;
goto endOfReadInt32;
}
param_index = VecUtils::getIndex(vmmHybPolarity_, function);
if (param_index >= 0) {
this->pVmmAPI->getHybPolarity(param_index, tmp_val_bool);
*value = tmp_val_bool;
goto endOfReadInt32;
}
endOfReadInt32:
if (param_index < 0) {
*value = 0;
return asynError;
}
setIntegerParam(function, *value);
callParamCallbacks();
return asynSuccess;
}
asynStatus VMMTbl::readOctet(asynUser *pasynUser, char *value,
size_t nChars, size_t *nActual,
int *eomReason)
{
int status = asynSuccess;
int function = pasynUser->reason;
std::string read = "";
/* If this parameter belongs to a base class call its method */
if (function < FIRST_VMM_PARAM) {
status = asynPortDriver::readOctet(pasynUser, value, nChars, nActual,
eomReason);
return (asynStatus)status;
}
//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) {
this->pVmmAPI->readFwVersion(param_index, read);
goto endOfReadOctet;
} }
param_index = VecUtils::getIndex(vmmHybId_, function);
if (param_index >= 0) {
this->pVmmAPI->readIDChip(param_index, read);
goto endOfReadOctet;
}
param_index = VecUtils::getIndex(vmmHybGeoPos_, function);
if (param_index >= 0) {
this->pVmmAPI->readGeoPos(param_index, read);
goto endOfReadOctet;
} }
endOfReadOctet:
if (param_index < 0) {
value[0] = '\0';
*nActual = 1;
return 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 asynSuccess;
} }
void VMMTbl::setInitialEpicsParams() { asynStatus VMMTbl::createParamAndStoreInVector(std::string paramName, asynParamType typ,
puts("set_initial_epics_params"); std::vector<int>* vectorToStore){
int paramIndex;
asynStatus status = createParam(paramName.c_str(), typ, &paramIndex);
if (status != asynSuccess) {
asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
"%s:%s: Failed to create paramter %s.\n",
driverName, __FUNCTION__, paramName.c_str());
return asynError;
}
vectorToStore->push_back(paramIndex);
return asynSuccess;
} }
asynStatus VMMTbl::createEpicsParams() { asynStatus VMMTbl::createEpicsParams() {
createParam("SEL_ANALOG_MONITOR_VMM0", asynParamInt32, &vmmSelectMonitorVMM0_);
createParam("SEL_ANALOG_MONITOR_VMM1", asynParamInt32, &vmmSelectMonitorVMM1_); createParam("REG_BANK_VERSION", asynParamInt32, &vmmRegBankVersion);
createParam("READ_ADC_VMMS", asynParamInt32, &vmmProcessReadMonitorVMMs_);
createParam("ADC_VALUE_VMM0", asynParamFloat64, &vmmMonitorValueVMM0_); std::tuple<std::string, asynParamType, std::vector<int>*>
createParam("ADC_VALUE_VMM1", asynParamFloat64, &vmmMonitorValueVMM1_); hyb_params_to_create[7] = {{"_FW_VERSION", asynParamOctet, &vmmHybFwVersion_},
createParam("VMM_FEN_ACQUIRE", asynParamInt32, &vmmAcquire_); {"_ID", asynParamOctet, &vmmHybId_},
{"_GEOPOS", asynParamOctet, &vmmHybGeoPos_},
for (int hyb = 0; hyb < number_hybrids; hyb++) { {"_LINK_STATUS", asynParamInt32, &vmmHybLinkStatus_},
std::ostringstream param_name; {"_SKEW", asynParamInt32, &vmmHybSkew_},
param_name << "HYB_" << hyb <<"_FW_VERSION"; {"_WIDTH", asynParamInt32, &vmmHybWidth_},
createParam(param_name.str().c_str(), asynParamOctet, &vmmHybFwVersion_[hyb]); {"_POLARITY", asynParamInt32, &vmmHybPolarity_}};
param_name.str("");
param_name << "HYB_" << hyb <<"_ID"; std::ostringstream param_name;
createParam(param_name.str().c_str(), asynParamOctet, &vmmHybId_[hyb]);
param_name.str(""); for (int hyb = 0; hyb < this->pVmmAPI->getNumHybrids(true); hyb++) {
param_name << "HYB_" << hyb <<"_GEOPOS";
createParam(param_name.str().c_str(), asynParamOctet, &vmmHybGeoPos_[hyb]); for (const auto& hyb_param : hyb_params_to_create){
param_name.str(""); const std::string& key = std::get<0>(hyb_param);
param_name << "HYB_" << hyb <<"_LINK_STATUS"; asynParamType typ = std::get<1>(hyb_param);
createParam(param_name.str().c_str(), asynParamInt32, &vmmHybLinkStatus_[hyb]); std::vector<int>* vec = std::get<2>(hyb_param);
for (int vmm=0; vmm < VMMS_PER_HYBRID; vmm++) createParamAndStoreInVector("HYB_" + std::to_string(hyb) + key, typ, vec);
{
param_name.str("");
param_name << "HYB_" << hyb <<"_" << vmm << "_ST";
createParam(param_name.str().c_str(), asynParamInt8Array, &vmmST_[hyb][vmm]);
param_name.str("");
param_name << "HYB_" << hyb <<"_" << vmm << "_SC";
createParam(param_name.str().c_str(), asynParamInt8Array, &vmmSC_[hyb][vmm]);
param_name.str("");
param_name << "HYB_" << hyb <<"_" << vmm << "_SL";
createParam(param_name.str().c_str(), asynParamInt8Array, &vmmSL_[hyb][vmm]);
param_name.str("");
param_name << "HYB_" << hyb <<"_" << vmm << "_STH";
createParam(param_name.str().c_str(), asynParamInt8Array, &vmmSTH_[hyb][vmm]);
param_name.str("");
param_name << "HYB_" << hyb <<"_" << vmm << "_SM";
createParam(param_name.str().c_str(), asynParamInt8Array, &vmmSM_[hyb][vmm]);
param_name.str("");
param_name << "HYB_" << hyb <<"_" << vmm << "_SMX";
createParam(param_name.str().c_str(), asynParamInt8Array, &vmmSMX_[hyb][vmm]);
} }
std::vector<int> SC, SL, ST, STH, SM, SMX;
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 << "_SMX";
createParamAndStoreInVector(param_name.str(), asynParamInt8Array, &SMX);
}
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->vmmSMX_.push_back(SMX);
} }
return asynSuccess; return asynSuccess;
} }
asynStatus VMMTbl::writeInt32(asynUser *pasynUser, epicsInt32 value) { asynStatus VMMTbl::writeInt32(asynUser *pasynUser, epicsInt32 value) {
asynStatus status = asynSuccess; asynStatus status = asynSuccess;
vmmStatus vmm_stat;
int function = pasynUser->reason; int function = pasynUser->reason;
int param_index = -1;
if ((value) && (function == vmmProcessReadMonitorVMMs_)) { // if (function == vmmAcquire_) {
int adc_sensor = 0;
for (int vmm = 0; vmm <= 1; vmm++) { // if (value) pVmmAPI->acquire(true);
getIntegerParam(vmmSelectMonitorVMM0_ + vmm, &adc_sensor); // else pVmmAPI->acquire(false);
std::cout << "adc_sensor" << adc_sensor << std::endl;
pVmmAPI->getHybrid(0).getVMM(vmm).setRegister("sm5_sm0", adc_sensor + 64); // for (int hyb = 0; hyb < number_hybrids; hyb++)
pVmmAPI->configVMM(0, vmm); // setIntegerParam(vmmHybLinkStatus_[hyb], std::stoi(pVmmAPI->checkLinkStatus(hyb)));
int adc_read = pVmmAPI->readADC(0, vmm); // }
std::cout << "adc_read" << adc_read << std::endl; if (function < FIRST_VMM_PARAM) {
return asynPortDriver::writeInt32(pasynUser, value);
if (adc_sensor == 3) {
double temperature = (725 - adc_read) / 1.85;
setDoubleParam(vmmMonitorValueVMM0_ + vmm, temperature);
}
else {
setDoubleParam(vmmMonitorValueVMM0_ + vmm, adc_read);
}
}
} }
else if (function == vmmAcquire_) { //Search for parameter in all parameter vectors. If found, execute correct function for specific hybrid.
param_index = VecUtils::getIndex(vmmHybSkew_, function);
if (value) pVmmAPI->acquire(true); if (param_index >= 0) {
else pVmmAPI->acquire(false); vmm_stat = this->pVmmAPI->setSkew(param_index, value);
if (vmm_stat != vmmSuccess) status = asynError;
goto endOfWriteInt32;
}
param_index = VecUtils::getIndex(vmmHybWidth_, function);
if (param_index >= 0) {
vmm_stat = this->pVmmAPI->setWidth(param_index, value);
if (vmm_stat != vmmSuccess) status = asynError;
goto endOfWriteInt32;
}
param_index = VecUtils::getIndex(vmmHybPolarity_, function);
if (param_index >= 0) {
vmm_stat = this->pVmmAPI->setHybPolarity(param_index, value);
if (vmm_stat != vmmSuccess) status = asynError;
goto endOfWriteInt32;
}
for (int hyb = 0; hyb < number_hybrids; hyb++) endOfWriteInt32:
setIntegerParam(vmmHybLinkStatus_[hyb], std::stoi(pVmmAPI->checkLinkStatus(hyb))); if (param_index < 0) {
status = asynError;
} }
setIntegerParam(function, value);
callParamCallbacks();
return status; return status;
} }
asynStatus VMMTbl::writeInt8Array(asynUser *pasynUser, epicsInt8 *value, size_t nElements) asynStatus VMMTbl::readInt8Array(asynUser *pasynUser, epicsInt8 *value, size_t nElements, size_t *nIn){
{
int function, addr; int function, hyb_index, vmm_index, found_param = -10, status = 0;
int ncopy = CHANNELS_PER_VMM; bool data;
const char *paramName; const char* paramName;
const char *functionName = "writeInt8Array";
int status = asynSuccess;
std::vector<epicsInt8> int8Array;
Reg pair;
status |= parseAsynUser(pasynUser, &function, &addr, &paramName); function = pasynUser->reason;
getParamName(function, &paramName); getParamName(function, &paramName);
status |= findRegister(function, &pair);
if (status) { if (function < FIRST_VMM_PARAM) return asynPortDriver::readInt8Array(pasynUser, value, nElements, nIn);
asynPrint(pasynUser, ASYN_TRACE_ERROR,
"%s:%s: function=%d, name=%s, value=%d. Cannot find which Hybrid-VMM pair is function related to.\n", found_param = VecUtils::getIndex(vmmST_, function, hyb_index, vmm_index);
driverName, functionName, function, paramName, *value); if (found_param == 0) {
return (asynStatus) status; for (size_t i = 0; i < nElements; i++) {
status |= (int)this->pVmmAPI->getST(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 paramter %s, index %d.\n",
driverName, __FUNCTION__, paramName, function);
*nIn = 0;
return asynError;
} }
asynPrint(pasynUser, ASYN_TRACEIO_DRIVER, *nIn = nElements;
"%s:%s: function=%d, name=%s, value=%d, hybrid=%d, vmm=%d, register=%s\n",
driverName, functionName, function, paramName, *value, pair.hyb, pair.vmm, pair.rg.c_str());
for (epicsInt8 i = 0; i < ncopy; ++i) { if (status) {
int8Array.push_back(static_cast<int>(value[i]) >= 1 ? 1 : 0); asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
pVmmAPI->getHybrid(pair.hyb).getVMM(pair.vmm).setRegister(pair.rg.c_str(), "%s:%s: Failed to get paramter %s, index %d.\n",
static_cast<int>(value[i]), driverName, __FUNCTION__, paramName, function);
i); return asynError;
} }
status |= doCallbacksInt8Array(int8Array.data(), int8Array.size(), function, 0); return asynSuccess;
return (asynStatus) status;
} }
asynStatus VMMTbl::findRegister(int function, Reg *reg_){ asynStatus VMMTbl::writeInt8Array(asynUser *pasynUser, epicsInt8 *value, size_t nElements)
{
int (*array)[VMMS_PER_HYBRID]; int function, hyb_index, vmm_index, status = 0, found_param = -10;
std::map<std::string, int(*)[VMMS_PER_HYBRID]>::iterator it; const char* paramName;
it = this->registers.begin(); function = pasynUser->reason;
getParamName(function, &paramName);
while ( it != this->registers.end() ){ if (function < FIRST_VMM_PARAM) return asynPortDriver::writeInt8Array(pasynUser, value, nElements);
std::string reg_name = it->first;
array = registers[reg_name];
for (int h = 0; h < number_hybrids; h++){ found_param = VecUtils::getIndex(vmmST_, function, hyb_index, vmm_index);
for (int v = 0; v < VMMS_PER_HYBRID; v++) if (found_param == 0) {
{ for (size_t i = 0; i < nElements; i++) {
if (array[h][v] == function){ status |= (int)this->pVmmAPI->setST(hyb_index, vmm_index, i, (bool)value[i]);
reg_->hyb = h;
reg_->vmm = v;
reg_->rg = reg_name;
return asynSuccess;
}
}
} }
goto endOfWriteInt8Array;
it++;
} }
return asynError; 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 paramter %s, index %d.\n",
driverName, __FUNCTION__, paramName, function);
return asynError;
}
} if (status) {
asynPrint(pasynUserSelf, ASYN_TRACE_ERROR,
"%s:%s: Failed to set paramter %s.\n",
driverName, __FUNCTION__, paramName);
return asynError;
}
asynStatus VMMTbl::writeFloat64(asynUser *pasynUser, epicsFloat64 value) { return asynSuccess;
asynStatus status = asynSuccess;
int addr = 0;
getAddress(pasynUser, &addr);
return status;
} }
extern "C" { extern "C" {
......
...@@ -2,49 +2,65 @@ ...@@ -2,49 +2,65 @@
#include "rmm.h" #include "rmm.h"
#include "VMMAPI.h" #include "VMMAPI.h"
#include "Utils.h"
/* Struct to hold Hyb, VMM pair values */ /* Struct to hold Hyb, VMM and epics parameter values */
struct Reg { struct ParamValues {
int hyb = -1; int param = -1;
int vmm = -1; std::string value;
std::string rg = "\0";
}; };
/** Class definition for the VMMTbl class */ /** Class definition for the VMMTbl class */
class VMMTbl : public asynPortDriver { class VMMTbl : public asynPortDriver {
public: public:
VMMTbl(RMM* rmm, const char *FENPortName, int ring, int node, int hybrids); VMMTbl(RMM* rmm, const char *FENPortName, int ring, int node, int hybrids);
/* Epics parameter management */
asynStatus createEpicsParams(); asynStatus createEpicsParams();
virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value); virtual asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
virtual asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value); // virtual asynStatus writeFloat64(asynUser *pasynUser, epicsFloat64 value);
virtual asynStatus writeInt8Array(asynUser *pasynUser, epicsInt8 *value, size_t nElements); virtual asynStatus writeInt8Array(asynUser *pasynUser, epicsInt8 *value, size_t nElements);
void setInitialEpicsParams(); virtual asynStatus readInt8Array(asynUser *pasynUser, epicsInt8 *value, size_t nElements, size_t *nIn);
asynStatus findRegister(int function, Reg *reg_); virtual asynStatus readInt32(asynUser *pasynUser, epicsInt32 *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);
protected: protected:
int vmmRegBankVersion;
#define FIRST_VMM_PARAM vmmRegBankVersion
int vmmSelectMonitorVMM0_; int vmmSelectMonitorVMM0_;
int vmmSelectMonitorVMM1_; int vmmSelectMonitorVMM1_;
int vmmProcessReadMonitorVMMs_; int vmmProcessReadMonitorVMMs_;
int vmmMonitorValueVMM0_; int vmmMonitorValueVMM0_;
int vmmMonitorValueVMM1_; int vmmMonitorValueVMM1_;
int vmmAcquire_; int vmmAcquire_;
int vmmHybFwVersion_[HYBRIDS_PER_FEN]; std::vector<int> vmmHybFwVersion_;
int vmmHybId_[HYBRIDS_PER_FEN]; std::vector<int> vmmHybId_;
int vmmHybGeoPos_[HYBRIDS_PER_FEN]; std::vector<int> vmmHybGeoPos_;
int vmmHybLinkStatus_[HYBRIDS_PER_FEN]; std::vector<int> vmmHybLinkStatus_;
//Registers channels per hybrid, per VMM std::vector<int> vmmHybSkew_;
int vmmST_[HYBRIDS_PER_FEN][VMMS_PER_HYBRID]; std::vector<int> vmmHybWidth_;
int vmmSL_[HYBRIDS_PER_FEN][VMMS_PER_HYBRID]; std::vector<int> vmmHybPolarity_;
int vmmSC_[HYBRIDS_PER_FEN][VMMS_PER_HYBRID]; std::vector<std::vector<int>> vmmSC_;
int vmmSTH_[HYBRIDS_PER_FEN][VMMS_PER_HYBRID]; std::vector<std::vector<int>> vmmSL_;
int vmmSM_[HYBRIDS_PER_FEN][VMMS_PER_HYBRID]; std::vector<std::vector<int>> vmmST_;
int vmmSMX_[HYBRIDS_PER_FEN][VMMS_PER_HYBRID]; std::vector<std::vector<int>> vmmSTH_;
std::map<std::string, int(*)[VMMS_PER_HYBRID]> registers{{"st", vmmST_}, {"sc", vmmSC_}, std::vector<std::vector<int>> vmmSM_;
{"sl", vmmSL_}, {"sth", vmmSTH_}, std::vector<std::vector<int>> vmmSD_;
{"sm", vmmSM_}, {"smx", vmmSMX_}}; std::vector<std::vector<int>> vmmSMX_;
// //Registers channels per hybrid, per VMM
// int vmmST_[HYBRIDS_PER_FEN][VMMS_PER_HYBRID];
// int vmmSL_[HYBRIDS_PER_FEN][VMMS_PER_HYBRID];
// int vmmSC_[HYBRIDS_PER_FEN][VMMS_PER_HYBRID];
// int vmmSTH_[HYBRIDS_PER_FEN][VMMS_PER_HYBRID];
// int vmmSM_[HYBRIDS_PER_FEN][VMMS_PER_HYBRID];
// int vmmSMX_[HYBRIDS_PER_FEN][VMMS_PER_HYBRID];
// std::map<std::string, int(*)[VMMS_PER_HYBRID]> registers{{"st", vmmST_}, {"sc", vmmSC_},
// {"sl", vmmSL_}, {"sth", vmmSTH_},
// {"sm", vmmSM_}, {"smx", vmmSMX_}};
private: private:
static constexpr const char *driverName = "VMMTbl"; static constexpr const char *driverName = "VMMTbl";
std::shared_ptr<VMMAPI> pVmmAPI; std::shared_ptr<VMMAPI> pVmmAPI;
int number_hybrids;
}; };
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment