need ot fix ctb tests as well, a lot of refactoring
All checks were successful
Build on RHEL9 / build (push) Successful in 3m23s
Build on RHEL8 / build (push) Successful in 5m4s

This commit is contained in:
2026-01-15 17:41:45 +01:00
parent 0aab505645
commit 0a69516459
11 changed files with 407 additions and 292 deletions

View File

@@ -1238,9 +1238,7 @@ void setDAC(enum DACINDEX ind, int val, int mV) {
// convert to dac units // convert to dac units
else if (LTC2620_VoltageToDac(val, &dacval) == OK) { else if (LTC2620_VoltageToDac(val, &dacval) == OK) {
dacValues[ind] = dacval; dacValues[ind] = dacval;
} } else if (LTC2620_SetDACValue((int)ind, val, mV, &dacval) == OK)
#else
if (LTC2620_SetDACValue((int)ind, val, mV, &dacval) == OK)
dacValues[ind] = dacval; dacValues[ind] = dacval;
#endif #endif
} }
@@ -1259,12 +1257,6 @@ int getDAC(enum DACINDEX ind, int mV) {
int getMaxDacSteps() { return LTC2620_GetMaxNumSteps(); } int getMaxDacSteps() { return LTC2620_GetMaxNumSteps(); }
int dacToVoltage(int dac) {
int val;
LTC2620_DacToVoltage(dac, &val);
return val;
}
int checkVLimitCompliant(int mV) { int checkVLimitCompliant(int mV) {
if (vLimit > 0 && mV > vLimit) if (vLimit > 0 && mV > vLimit)
return FAIL; return FAIL;
@@ -1352,7 +1344,13 @@ int getVChipToSet(enum DACINDEX ind, int val) {
for (int ipwr = 0; ipwr < NPWR - 1; ++ipwr) { for (int ipwr = 0; ipwr < NPWR - 1; ++ipwr) {
// get the dac values for each adc // get the dac values for each adc
int dacmV = getPower(getDACIndexFromADCIndex(ipwr)); char emsg[MAX_STR_LENGTH];
int dacmV = -1;
if (getPower(ipwr, &dacmV, emsg) == FAIL) {
LOG(logERROR, ("Could not get power %d to calculate vchip. %s\n",
ipwr, emsg));
return -1;
}
// if current index, replace with value to be set // if current index, replace with value to be set
if (ipwr == adcIndex) { if (ipwr == adcIndex) {
@@ -1378,6 +1376,42 @@ int getVChipToSet(enum DACINDEX ind, int val) {
return max; return max;
} }
int dacToVoltage_PowerRegulators(int pwrIndex, int dac_value, int *retval_mV,
char *mess) {
*retval_mV = -1;
char *powerNames[] = {PWR_NAMES};
if (ConvertToDifferentRange(LTC2620_GetMaxInput(), LTC2620_GetMinInput(),
POWER_RGLTR_MIN, POWER_RGLTR_MAX, dac_value,
retval_mV) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not convert dac value %d to mV for Power %s\n",
dac_value, powerNames[pwrIndex]);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int voltageToDac_PowerRegulators(int pwrIndex, int voltage, int *retval_dac,
char *mess) {
*retval_dac = -1;
char *powerNames[] = {PWR_NAMES};
if (ConvertToDifferentRange(POWER_RGLTR_MIN, POWER_RGLTR_MAX,
LTC2620_GetMaxInput(), LTC2620_GetMinInput(),
voltage, retval_dac) == FAIL) {
int min = pwrIndex == V_PWR_IO ? VIO_MIN_MV : POWER_RGLTR_MIN;
int max = getVchip() - VCHIP_POWER_INCRMNT;
snprintf(mess, MAX_STR_LENGTH,
"Could not convert Power %s to dac value. Invalid value of "
"%d mV. Should be between %d and %d mV\n",
powerNames[pwrIndex], voltage, min, max);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int getDACIndexFromADCIndex(enum ADCINDEX ind) { int getDACIndexFromADCIndex(enum ADCINDEX ind) {
switch (ind) { switch (ind) {
case V_PWR_IO: case V_PWR_IO:
@@ -1414,46 +1448,103 @@ int getADCIndexFromDACIndex(enum DACINDEX ind) {
} }
} }
int isPowerValid(enum DACINDEX ind, int val) { void powerEnable(int on, int pwrIndex) {
int min = (ind == D_PWR_IO) ? VIO_MIN_MV : POWER_RGLTR_MIN; uint32_t addr = POWER_REG;
int offset = POWER_ENBL_VLTG_RGLTR_OFST + pwrIndex;
uint32_t mask = (1 << offset);
if (on) {
// Switch on power enable
LOG(logINFO, ("\tSwitching on power enable\n"));
bus_w(addr, bus_r(addr) | mask);
} else {
// Switch off power enable
LOG(logINFO, ("\tSwitching off power enable\n"));
bus_w(addr, bus_r(addr) & ~(mask));
}
}
int getPowerEnable(int pwrIndex) {
int offset = POWER_ENBL_VLTG_RGLTR_OFST + pwrIndex;
uint32_t mask = (1 << offset);
return (bus_r(POWER_REG) & mask);
}
int isPowerValid(enum DACINDEX ind, int val, char *mess) {
char *powerNames[] = {PWR_NAMES};
// validate & get power index
int pwrIndex = getADCIndexFromDACIndex(ind);
if (pwrIndex == -1) {
snprintf(mess, MAX_STR_LENGTH,
"Could not validate power. Invalid DAC index: %d for Power\n",
ind);
LOG(logERROR, (mess));
return FAIL;
}
// check vlimit
if (checkVLimitCompliant(val) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Power %s value %d mV exceeds vLimit of %d mV\n",
powerNames[pwrIndex], val, vLimit);
LOG(logERROR, (mess));
return FAIL;
}
// validate within bounds
// not power_rgltr_max because it is allowed only upto vchip max - 200 // not power_rgltr_max because it is allowed only upto vchip max - 200
if (val != 0 && (val != LTC2620_GetPowerDownValue()) && int min = pwrIndex == V_PWR_IO ? VIO_MIN_MV : POWER_RGLTR_MIN;
(val < min || val > (VCHIP_MAX_MV - VCHIP_POWER_INCRMNT))) { int max = VCHIP_MAX_MV - VCHIP_POWER_INCRMNT;
return 0; if ((val != 0 && (val != LTC2620_GetPowerDownValue()) && val < min) ||
val > max) {
snprintf(mess, MAX_STR_LENGTH,
"Invalid value of %d mV for Power %s. Can be -100, 0 or "
"between %d and %d mV\n",
val, powerNames[pwrIndex], min, max);
LOG(logERROR, (mess));
return FAIL;
} }
return 1; return OK;
} }
int getPower(enum DACINDEX ind) { int getPower(enum DACINDEX ind, int *retval, char *mess) {
// validate index & get adc index *retval = -1;
int adcIndex = getADCIndexFromDACIndex(ind); char *powerNames[] = {PWR_NAMES};
if (adcIndex == -1) {
return -1; // validate & get power index
int pwrIndex = getADCIndexFromDACIndex(ind);
if (pwrIndex == -1) {
snprintf(mess, MAX_STR_LENGTH,
"Could not validate power. Invalid DAC index: %d for Power\n",
ind);
LOG(logERROR, (mess));
return FAIL;
} }
// powered enable off // powered enable off
{ if (getPowerEnable(pwrIndex) == 0) {
uint32_t addr = POWER_REG; *retval = 0;
uint32_t offset = POWER_ENBL_VLTG_RGLTR_OFST + adcIndex; return OK;
uint32_t mask = (1 << offset);
if (!(bus_r(addr) & mask))
return 0;
} }
// not set yet // dac value not set by user yet
if (dacValues[ind] == -1) { if (dacValues[ind] == -1) {
LOG(logERROR, snprintf(mess, MAX_STR_LENGTH,
("Power enabled, but unknown dac value for power index %d!", ind)); "Power %s not initialized to a value yet (other than 0). "
return -1; "Cannot get value.\n",
powerNames[pwrIndex]);
LOG(logERROR, (mess));
return FAIL;
} }
// dac powered off // dac powered down
if (dacValues[ind] == LTC2620_GetPowerDownValue()) { if (dacValues[ind] == LTC2620_GetPowerDownValue()) {
LOG(logWARNING, LOG(logWARNING,
("Power %d enabled, dac value %d, voltage at minimum or 0\n", ind, ("Power %d enabled, dac value %d, voltage at minimum or 0\n", ind,
LTC2620_GetPowerDownValue())); LTC2620_GetPowerDownValue()));
return LTC2620_GetPowerDownValue(); *retval = LTC2620_GetPowerDownValue();
return OK;
} }
// vchip not set, weird error, should not happen (as vchip set to max in the // vchip not set, weird error, should not happen (as vchip set to max in the
@@ -1461,66 +1552,70 @@ int getPower(enum DACINDEX ind) {
// tried to get a power regulator value // tried to get a power regulator value
if (dacValues[D_PWR_CHIP] == -1 || if (dacValues[D_PWR_CHIP] == -1 ||
dacValues[D_PWR_CHIP] == LTC2620_GetPowerDownValue()) { dacValues[D_PWR_CHIP] == LTC2620_GetPowerDownValue()) {
LOG(logERROR, ("Cannot read power regulator %d (vchip not set)." snprintf(mess, MAX_STR_LENGTH,
"Set a power regulator, which will also set vchip.\n")); "Power %s cannot be read as vchip is not set. Set a power "
return -1; "regulator first, which will also set vchip.\n",
powerNames[pwrIndex]);
LOG(logERROR, (mess));
return FAIL;
} }
// convert dac to voltage // get dac in mV
int retval = -1; if (dacToVoltage_PowerRegulators(pwrIndex, dacValues[ind], retval, mess) ==
ConvertToDifferentRange(LTC2620_GetMaxInput(), LTC2620_GetMinInput(), FAIL)
POWER_RGLTR_MIN, POWER_RGLTR_MAX, dacValues[ind], return FAIL;
&retval);
return retval; return OK;
} }
void setPower(enum DACINDEX ind, int val) { int setPower(enum DACINDEX ind, int val, char *mess) {
// validate index & get adc index char *powerNames[] = {PWR_NAMES};
int adcIndex = getADCIndexFromDACIndex(ind);
if (adcIndex == -1) { // validate & get power index
return; int pwrIndex = getADCIndexFromDACIndex(ind);
if (pwrIndex == -1) {
snprintf(mess, MAX_STR_LENGTH,
"Could not validate power. Invalid DAC index: %d for Power\n",
ind);
LOG(logERROR, (mess));
return FAIL;
} }
uint32_t addr = POWER_REG; if (isPowerValid(ind, val, mess) == FAIL) {
uint32_t offset = POWER_ENBL_VLTG_RGLTR_OFST + adcIndex; return FAIL;
uint32_t mask = (1 << offset);
// set power
if (val != -1) {
LOG(logINFO, ("Setting Power to %d mV\n", val));
// validate value (already checked at tcp)
if (!isPowerValid(ind, val)) {
LOG(logERROR,
("Invalid value of %d mV for Power %d. Is not between %d and "
"%d mV\n",
val, ind, (ind == D_PWR_IO ? VIO_MIN_MV : POWER_RGLTR_MIN),
POWER_RGLTR_MAX));
return;
} }
LOG(logINFO, ("Setting Power %s to %d mV\n", powerNames[pwrIndex], val));
// get vchip to set vchip (calculated now before switching off power // get vchip to set vchip (calculated now before switching off power
// enable) // enable)
int vchip = getVChipToSet(ind, val); int vchip = getVChipToSet(ind, val);
LOG(logDEBUG1, ("Vchip to set: %d\n", vchip)); LOG(logDEBUG1, ("Vchip to set: %d\n", vchip));
// index problem of vchip calculation problem // index issue of vchip calculation
if (vchip == -1) if (vchip == -1) {
return; snprintf(mess, MAX_STR_LENGTH,
"Could not set power %s. Calculated vchip to set is beyond "
"its maximum range.\n",
powerNames[pwrIndex]);
LOG(logERROR, (mess));
return FAIL;
}
// Switch off power enable powerEnable(0, pwrIndex);
LOG(logDEBUG1, ("Switching off power enable\n"));
bus_w(addr, bus_r(addr) & ~(mask));
// power down dac // power down dac
LOG(logDEBUG1, ("Powering off P%d (DAC %d)\n", adcIndex, ind)); LOG(logDEBUG1, ("Powering off %s\n", powerNames[pwrIndex]));
setDAC(ind, LTC2620_GetPowerDownValue(), 0); setDAC(ind, LTC2620_GetPowerDownValue(), 0);
// set vchip // set vchip
setVchip(vchip); setVchip(vchip);
if (getVchip() != vchip) { if (getVchip() != vchip) {
LOG(logERROR, ("Weird, Could not set vchip. Set %d, read %d\n.", snprintf(mess, MAX_STR_LENGTH,
vchip, getVchip())); "Could not set power %s. Tried to set vchip to %d mV, read %d "
return; "mV\n.",
powerNames[pwrIndex], vchip, getVchip());
LOG(logERROR, (mess));
return FAIL;
} }
//(power off is anyway done with power enable) //(power off is anyway done with power enable)
@@ -1529,32 +1624,28 @@ void setPower(enum DACINDEX ind, int val) {
// convert it to dac (power off is anyway done with power enable) // convert it to dac (power off is anyway done with power enable)
if (val != LTC2620_GetPowerDownValue()) { if (val != LTC2620_GetPowerDownValue()) {
LOG(logDEBUG1, ("Convert Power of %d mV to dac units\n", val));
// convert mV to dac value
int dacval = -1; int dacval = -1;
// convert voltage to dac if (voltageToDac_PowerRegulators(pwrIndex, val, &dacval, mess) == FAIL)
if (ConvertToDifferentRange( return FAIL;
POWER_RGLTR_MIN, POWER_RGLTR_MAX, LTC2620_GetMaxInput(),
LTC2620_GetMinInput(), val, &dacval) == FAIL) {
LOG(logERROR,
("\tPower index %d of value %d mV invalid. Is not between "
"%d and %d mV\n",
ind, val, POWER_RGLTR_MIN, vchip - VCHIP_POWER_INCRMNT));
return;
}
// set and power on/ update dac // set dac value
LOG(logINFO, ("Setting P%d (DAC %d): %d dac (%d mV)\n", adcIndex, LOG(logINFO, ("\tSetting %s: %d mV (%d dac)\n", powerNames[pwrIndex],
ind, dacval, val)); val, dacval));
setDAC(ind, dacval, 0); setDAC(ind, dacval, 0);
if (dacval == -1) {
snprintf(mess, MAX_STR_LENGTH,
"Could not set power %s. Tried to set dac value to %d\n.",
powerNames[pwrIndex], dacval);
LOG(logERROR, (mess));
return FAIL;
}
// to be sure of valid conversion powerEnable(1, pwrIndex);
if (dacval >= 0) {
LOG(logDEBUG1, ("Switching on power enable\n"));
bus_w(addr, bus_r(addr) | mask);
}
}
} }
return OK;
} }
void powerOff() { void powerOff() {

View File

@@ -147,6 +147,8 @@ enum ADCINDEX {
S_ADC7, S_ADC7,
S_TMP S_TMP
}; };
#define PWR_NAMES "VIO", "VA", "VB", "VC", "VD"
enum DACINDEX { enum DACINDEX {
D0, D0,
D1, D1,
@@ -173,5 +175,6 @@ enum DACINDEX {
D_PWR_A, D_PWR_A,
D_PWR_IO D_PWR_IO
}; };
enum CLKINDEX { RUN_CLK, ADC_CLK, SYNC_CLK, DBIT_CLK, NUM_CLOCKS }; enum CLKINDEX { RUN_CLK, ADC_CLK, SYNC_CLK, DBIT_CLK, NUM_CLOCKS };
#define CLK_NAMES "run", "adc", "sync", "dbit" #define CLK_NAMES "run", "adc", "sync", "dbit"

View File

@@ -381,7 +381,16 @@ void setDAC(enum DACINDEX ind, int val, int mV);
int getDAC(enum DACINDEX ind, int mV); int getDAC(enum DACINDEX ind, int mV);
int getMaxDacSteps(); int getMaxDacSteps();
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD) #if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD)
int dacToVoltage(int dac); int dacToVoltage_PowerRegulators(int pwrIndex, int dac_value, int *retval,
char *mess);
int voltageToDac_PowerRegulators(int pwrIndex, int voltage, int *retval,
char *mess);
void powerEnable(int on, int pwrIndex);
int getPowerEnable(int pwrIndex);
int isPowerValid(enum DACINDEX ind, int val, char *mess);
int getPower(enum DACINDEX ind, int *retval, char *mess);
int setPower(enum DACINDEX ind, int val, char *mess);
int checkVLimitCompliant(int mV); int checkVLimitCompliant(int mV);
int checkVLimitDacCompliant(int dac); int checkVLimitDacCompliant(int dac);
int getVLimit(); int getVLimit();
@@ -395,16 +404,11 @@ void setVchip(int val);
int getVChipToSet(enum DACINDEX ind, int val); int getVChipToSet(enum DACINDEX ind, int val);
int getDACIndexFromADCIndex(enum ADCINDEX ind); int getDACIndexFromADCIndex(enum ADCINDEX ind);
int getADCIndexFromDACIndex(enum DACINDEX ind); int getADCIndexFromDACIndex(enum DACINDEX ind);
int isPowerValid(enum DACINDEX ind, int val);
int getPower();
void setPower(enum DACINDEX ind, int val);
void powerOff(); void powerOff();
#elif XILINX_CHIPTESTBOARDD #elif XILINX_CHIPTESTBOARDD
int getPwrIndex(enum DACINDEX ind);
int getBitOffsetFromDACIndex(enum DACINDEX ind); int getBitOffsetFromDACIndex(enum DACINDEX ind);
int getMinPowerValue(enum DACINDEX ind);
int isPowerValid(enum DACINDEX ind, int val);
int getPower();
int setPower(enum DACINDEX ind, int val);
#endif #endif
#if defined(MYTHEN3D) || defined(GOTTHARD2D) || defined(XILINX_CHIPTESTBOARDD) #if defined(MYTHEN3D) || defined(GOTTHARD2D) || defined(XILINX_CHIPTESTBOARDD)

View File

@@ -1283,48 +1283,14 @@ int validateAndSetDac(enum dacIndex ind, int val, int mV) {
"exceeds voltage limit %d.\n", "exceeds voltage limit %d.\n",
ind, getVLimit()); ind, getVLimit());
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} } else {
ret = setPower(serverDacIndex, val, mess);
else if (!isPowerValid(serverDacIndex, val)) {
ret = FAIL;
sprintf(
mess,
"Could not set power. Power regulator %d "
"should be between %d and %d mV\n",
ind,
(serverDacIndex == D_PWR_IO ? VIO_MIN_MV : POWER_RGLTR_MIN),
#ifdef CHIPTESTBOARDD
(VCHIP_MAX_MV - VCHIP_POWER_INCRMNT));
#else
POWER_RGLTR_MAX);
#endif
LOG(logERROR, (mess));
}
else {
#ifdef XILINX_CHIPTESTBOARDD
ret = setPower(serverDacIndex, val);
if (ret == FAIL) {
sprintf(mess,
"Setting power regulator %d to value %d failed.\n",
serverDacIndex, val);
LOG(logERROR, (mess));
}
#else
setPower(serverDacIndex, val);
#endif
} }
} }
if (ret == OK) { if (ret == OK) {
retval = getPower(serverDacIndex); ret = getPower(serverDacIndex, &retval, mess);
LOG(logDEBUG1, LOG(logDEBUG1,
("Power regulator(%d): %d\n", serverDacIndex, retval)); ("Power regulator(%d): %d\n", serverDacIndex, retval));
if (retval == -1) {
ret = FAIL;
sprintf(mess, "Could not get power regulator %d.\n",
serverDacIndex);
LOG(logERROR, (mess));
}
validate(&ret, mess, val, retval, "set/get power regulator", DEC); validate(&ret, mess, val, retval, "set/get power regulator", DEC);
} }
break; break;
@@ -1401,9 +1367,9 @@ int validateAndSetDac(enum dacIndex ind, int val, int mV) {
checkVLimitDacCompliant(val) == FAIL)) { checkVLimitDacCompliant(val) == FAIL)) {
ret = FAIL; ret = FAIL;
sprintf(mess, sprintf(mess,
"Could not set dac %d to value %d. " "Could not set dac %d. "
"Exceeds voltage limit %d.\n", "Exceeds voltage limit %d mV.\n",
ind, (mV ? val : dacToVoltage(val)), getVLimit()); ind, getVLimit());
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} else } else
#endif #endif

View File

@@ -414,13 +414,21 @@ void setupDetector() {
LOG(logINFOBLUE, ("Powering down all dacs\n")); LOG(logINFOBLUE, ("Powering down all dacs\n"));
for (int idac = 0; idac < NDAC_ONLY; ++idac) { for (int idac = 0; idac < NDAC_ONLY; ++idac) {
setDAC(idac, LTC2620_D_GetPowerDownValue(), 0); initError = setDAC(idac, LTC2620_D_GetPowerDownValue(), 0);
if (initError == FAIL) {
snprintf(initErrorMessage, MAX_STR_LENGTH,
"Could not power down dac %d\n", idac);
LOG(logERROR, (initErrorMessage));
return;
}
} }
LOG(logINFOBLUE, ("Defaulting all power regulators to minimum.\n")); LOG(logINFOBLUE, ("Defaulting all power regulators to minimum.\n"));
for (int idac = NDAC_ONLY; idac < NDAC; ++idac) { for (int idac = NDAC_ONLY; idac < NDAC; ++idac) {
if (idac == D_PWR_EMPTY) if (idac == D_PWR_EMPTY)
continue; continue;
setPower(idac, 0); initError = setPower(idac, 0, initErrorMessage);
if (initError == FAIL)
return;
} }
resetFlow(); resetFlow();
@@ -1205,8 +1213,8 @@ int getDAC(enum DACINDEX ind, int mV) {
return dacValues[ind]; return dacValues[ind];
} }
// convert dac units to mV // convert dac units to mV
int voltage = dacToVoltage(dacValues[ind]); int voltage = -1;
if (voltage == -1) { if (LTC2620_D_DacToVoltage(dacValues[ind], &voltage) == FAIL) {
LOG(logERROR, ("Could not convert %d dac units to mV for dac %d\n", LOG(logERROR, ("Could not convert %d dac units to mV for dac %d\n",
dacValues[ind], ind)); dacValues[ind], ind));
return -1; return -1;
@@ -1218,14 +1226,6 @@ int getDAC(enum DACINDEX ind, int mV) {
int getMaxDacSteps() { return LTC2620_D_GetMaxNumSteps(); } int getMaxDacSteps() { return LTC2620_D_GetMaxNumSteps(); }
int dacToVoltage(int dac) {
int val;
if (LTC2620_D_DacToVoltage(dac, &val) == FAIL) {
return -1;
}
return val;
}
int checkVLimitCompliant(int mV) { int checkVLimitCompliant(int mV) {
if (vLimit > 0 && mV > vLimit) if (vLimit > 0 && mV > vLimit)
return FAIL; return FAIL;
@@ -1251,156 +1251,194 @@ void setVLimit(int l) {
vLimit = l; vLimit = l;
} }
int getBitOffsetFromDACIndex(enum DACINDEX ind) { int dacToVoltage_PowerRegulators(int pwrIndex, int dac_value, int *retval_mV,
char *mess) {
*retval_mV = -1;
char *powerNames[] = {PWR_NAMES};
if (ConvertToDifferentRange(
LTC2620_D_GetMaxInput(), LTC2620_D_GetMinInput(), POWER_RGLTR_MIN,
POWER_RGLTR_MAX, dac_value, retval_mV) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not convert dac value %d to mV for Power %s\n",
dac_value, powerNames[pwrIndex]);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int voltageToDac_PowerRegulators(int pwrIndex, int voltage, int *retval_dac,
char *mess) {
*retval_dac = -1;
char *powerNames[] = {PWR_NAMES};
if (ConvertToDifferentRange(
POWER_RGLTR_MIN, POWER_RGLTR_MAX, LTC2620_D_GetMaxInput(),
LTC2620_D_GetMinInput(), voltage, retval_dac) == FAIL) {
int min = pwrIndex == V_PWR_IO ? VIO_MIN_MV : POWER_RGLTR_MIN;
snprintf(mess, MAX_STR_LENGTH,
"Could not convert Power %s to dac value. Invalid value of "
"%d mV. Should be between %d and %d mV\n",
powerNames[pwrIndex], voltage, min, POWER_RGLTR_MAX);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int getPwrIndex(enum DACINDEX ind) {
switch (ind) { switch (ind) {
case D_PWR_IO: case D_PWR_IO:
return POWER_VIO_OFST; return V_PWR_IO; // same as POWER_VIO_OFST
case D_PWR_A: case D_PWR_A:
return POWER_VCC_A_OFST; return V_PWR_A; // same as POWER_VCC_A_OFST
case D_PWR_B: case D_PWR_B:
return POWER_VCC_B_OFST; return V_PWR_B; // same as POWER_VCC_B_OFST
case D_PWR_C: case D_PWR_C:
return POWER_VCC_C_OFST; return V_PWR_C; // same as POWER_VCC_C_OFST
case D_PWR_D: case D_PWR_D:
return POWER_VCC_D_OFST; return V_PWR_D; // same as POWER_VCC_D_OFST
default: default:
LOG(logERROR, LOG(logERROR, ("DAC index %d is not defined for Power\n", ind));
("DAC index %d is not defined to get offset in ctrl register\n",
ind));
return -1; return -1;
} }
} }
int getMinPowerValue(enum DACINDEX ind) { void powerEnable(int on, int pwrIndex) {
if (ind < D_PWR_D || ind > D_PWR_C || ind == D_PWR_EMPTY) {
LOG(logERROR, ("Invalid Power DAC index: %d\n", ind));
return -1;
}
if (ind == D_PWR_IO) {
return VIO_MIN_MV;
}
return POWER_RGLTR_MIN;
}
int isPowerValid(enum DACINDEX ind, int val) {
if (ind < D_PWR_D || ind > D_PWR_C || ind == D_PWR_EMPTY) {
LOG(logERROR, ("Invalid Power DAC index: %d\n", ind));
return -1;
}
char *powerNames[] = {PWR_NAMES};
int pwrIndex = (int)(ind - D_PWR_D);
int min = getMinPowerValue(ind);
// check vlimit (already checked at funcs.c)
if (checkVLimitCompliant(val) == FAIL) {
LOG(logERROR,
("Invalid value of %d mV for Power %s. Exceeds vLimit of %d mV\n",
val, powerNames[pwrIndex], vLimit));
return 0;
}
// not power_rgltr_max because it is allowed only upto vchip max - 200
if ((val != 0 && val < min) || val > POWER_RGLTR_MAX) {
LOG(logERROR,
("Invalid value of %d mV for Power %s. Is not between %d and "
"%d mV\n",
val, powerNames[pwrIndex], min, POWER_RGLTR_MAX));
return 0;
}
return 1;
}
int getPower(enum DACINDEX ind) {
if (ind < D_PWR_D || ind > D_PWR_C || ind == D_PWR_EMPTY) {
LOG(logERROR, ("Invalid Power DAC index: %d\n", ind));
return -1;
}
// get bit offset in ctrl register
int bitOffset = getBitOffsetFromDACIndex(ind);
if (bitOffset == -1) {
return -1;
}
// powered enable off
{
uint32_t addr = CTRL_REG; uint32_t addr = CTRL_REG;
uint32_t mask = (1 << bitOffset); uint32_t mask = (1 << pwrIndex);
if (!(bus_r(addr) & mask))
return 0; if (on) {
// Switch on power enable
LOG(logINFO, ("\tSwitching on power enable\n"));
bus_w(addr, bus_r(addr) | mask);
} else {
// Switch off power enable
LOG(logINFO, ("\tSwitching off power enable\n"));
bus_w(addr, bus_r(addr) & ~(mask));
}
} }
char *powerNames[] = {PWR_NAMES}; int getPowerEnable(int pwrIndex) {
int pwrIndex = (int)(ind - D_PWR_D); uint32_t mask = (1 << pwrIndex);
int min = getMinPowerValue(ind); return (bus_r(CTRL_REG) & mask);
}
// not set yet int isPowerValid(enum DACINDEX ind, int val, char *mess) {
char *powerNames[] = {PWR_NAMES};
// validate & get power index
int pwrIndex = getPwrIndex(ind);
if (pwrIndex == -1) {
snprintf(mess, MAX_STR_LENGTH,
"Could not validate power. Invalid DAC index: %d for Power\n",
ind);
LOG(logERROR, (mess));
return FAIL;
}
// check vlimit
if (checkVLimitCompliant(val) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Power %s value %d mV exceeds vLimit of %d mV\n",
powerNames[pwrIndex], val, vLimit);
LOG(logERROR, (mess));
return FAIL;
}
// validate within bounds
int min = pwrIndex == V_PWR_IO ? VIO_MIN_MV : POWER_RGLTR_MIN;
int max = POWER_RGLTR_MAX;
if ((val != 0 && val < min) || val > max) {
snprintf(mess, MAX_STR_LENGTH,
"Invalid value of %d mV for Power %s. Can be 0 or between %d "
"and %d mV\n",
val, powerNames[pwrIndex], min, max);
LOG(logERROR, (mess));
return FAIL;
}
return OK;
}
int getPower(enum DACINDEX ind, int *retval, char *mess) {
*retval = -1;
char *powerNames[] = {PWR_NAMES};
// validate & get power index
int pwrIndex = getPwrIndex(ind);
if (pwrIndex == -1) {
snprintf(mess, MAX_STR_LENGTH,
"Could not validate power. Invalid DAC index: %d for Power\n",
ind);
LOG(logERROR, (mess));
return FAIL;
}
// powered off
if (getPowerEnable(pwrIndex) == 0) {
*retval = 0;
return OK;
}
// dac value not set by user yet
if (dacValues[ind] == -1) { if (dacValues[ind] == -1) {
LOG(logERROR, snprintf(mess, MAX_STR_LENGTH,
("Unknown dac value for Power %s!\n", powerNames[pwrIndex])); "Power %s not initialized to a value yet (other than 0). "
return -1; "Cannot get value.\n",
powerNames[pwrIndex]);
LOG(logERROR, (mess));
return FAIL;
} }
// get dac in mV // get dac in mV
int retval = -1; if (dacToVoltage_PowerRegulators(pwrIndex, dacValues[ind], retval, mess) ==
ConvertToDifferentRange(LTC2620_D_GetMaxInput(), LTC2620_D_GetMinInput(),
min, POWER_RGLTR_MAX, dacValues[ind], &retval);
return retval;
}
int setPower(enum DACINDEX ind, int val) {
if (ind < D_PWR_D || ind > D_PWR_C || ind == D_PWR_EMPTY) {
LOG(logERROR, ("Invalid Power DAC index: %d\n", ind));
return FAIL;
}
if (!isPowerValid(ind, val)) {
return FAIL;
}
// validate index and get bit offset in ctrl register
int bitOffset = getBitOffsetFromDACIndex(ind);
if (bitOffset == -1) {
return FAIL;
}
uint32_t addr = CTRL_REG;
uint32_t mask = (1 << bitOffset);
char *powerNames[] = {PWR_NAMES};
int pwrIndex = (int)(ind - D_PWR_D);
int min = getMinPowerValue(ind);
LOG(logINFO, ("Setting Power %s to %d mV\n", powerNames[pwrIndex], val));
// Switch off power enable
LOG(logDEBUG1, ("\tSwitching off power enable\n"));
bus_w(addr, bus_r(addr) & ~(mask));
if (val > 0) {
// convert voltage to dac
int dacval = -1;
if (ConvertToDifferentRange(
min, POWER_RGLTR_MAX, LTC2620_D_GetMaxInput(),
LTC2620_D_GetMinInput(), val, &dacval) == FAIL) {
LOG(logERROR,
("\tCannot convert Power %s to dac value. Invalid value of %d "
"mV. Is not between "
"%d and %d mV\n",
powerNames[pwrIndex], val, min, POWER_RGLTR_MAX));
return FAIL;
}
// set dac value
LOG(logINFO, ("\tSetting DAC %s: %d mV (%d dac)\n",
powerNames[pwrIndex], val, dacval));
if (LTC2620_D_WriteDACValue((int)ind, dacval, powerNames[pwrIndex]) ==
FAIL) FAIL)
return FAIL; return FAIL;
return OK;
}
int setPower(enum DACINDEX ind, int val, char *mess) {
char *powerNames[] = {PWR_NAMES};
// validate & get power index
int pwrIndex = getPwrIndex(ind);
if (pwrIndex == -1) {
snprintf(mess, MAX_STR_LENGTH,
"Could not validate power. Invalid DAC index: %d for Power\n",
ind);
LOG(logERROR, (mess));
return FAIL;
}
if (isPowerValid(ind, val, mess) == FAIL) {
return FAIL;
}
LOG(logINFO, ("Setting Power %s to %d mV\n", powerNames[pwrIndex], val));
powerEnable(0, pwrIndex);
if (val > 0) {
// convert mV to dac value
int dacval = -1;
if (voltageToDac_PowerRegulators(pwrIndex, val, &dacval, mess) == FAIL)
return FAIL;
// set dac value
LOG(logINFO, ("\tSetting %s: %d mV (%d dac)\n", powerNames[pwrIndex],
val, dacval));
if (LTC2620_D_WriteDACValue((int)ind, dacval, powerNames[pwrIndex]) ==
FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not set Power %s to %d mV. Could not write to "
"file.\n",
powerNames[pwrIndex], val);
LOG(logERROR, (mess));
return FAIL;
}
dacValues[ind] = dacval; dacValues[ind] = dacval;
// Switch on power enable powerEnable(1, pwrIndex);
LOG(logDEBUG1, ("\tSwitching on power enable for Power %s\n",
powerNames[pwrIndex]));
bus_w(addr, bus_r(addr) | mask);
} }
return OK; return OK;

View File

@@ -119,7 +119,15 @@ enum DACINDEX {
D_PWR_C D_PWR_C
}; };
#define PWR_NAMES "VD", "_unknown", "VIO", "VA", "VB", "VC" enum PWDINDEX {
V_PWR_IO,
V_PWR_A,
V_PWR_B,
V_PWR_C,
V_PWR_D,
};
#define PWR_NAMES "VIO", "VA", "VB", "VC", "VD"
/* Struct Definitions */ /* Struct Definitions */
// For arm has to be multiple of 16 // For arm has to be multiple of 16

View File

@@ -1060,9 +1060,9 @@ TEST_CASE("v_abcd", "[.cmdcall]") {
if (det_type == defs::XILINX_CHIPTESTBOARD && if (det_type == defs::XILINX_CHIPTESTBOARD &&
det.isVirtualDetectorServer().tsquash( det.isVirtualDetectorServer().tsquash(
"inconsistent virtual values")) { "inconsistent virtual values")) {
// prev value for power regulators should have been 0 // prev value for power regulators should have been 1200
// as they are only touched in this test // (set in config) as they are only touched in this test
REQUIRE(prev_val.squash(-1) == 0); REQUIRE(prev_val.squash(-1) == 1200);
REQUIRE_THROWS(caller.call(cmds[i], {"-100"}, -1, PUT)); REQUIRE_THROWS(caller.call(cmds[i], {"-100"}, -1, PUT));
} }

View File

@@ -3,10 +3,10 @@
/** API versions */ /** API versions */
#define APILIB "0.0.0 0x250909" #define APILIB "0.0.0 0x250909"
#define APIRECEIVER "0.0.0 0x250822" #define APIRECEIVER "0.0.0 0x250822"
#define APICTB "0.0.0 0x250922" #define APICTB "0.0.0 0x260115"
#define APIGOTTHARD2 "0.0.0 0x260114" #define APIGOTTHARD2 "0.0.0 0x260114"
#define APIMOENCH "0.0.0 0x250909" #define APIMOENCH "0.0.0 0x250909"
#define APIEIGER "0.0.0 0x250909" #define APIEIGER "0.0.0 0x250909"
#define APIXILINXCTB "0.0.0 0x260114" #define APIXILINXCTB "0.0.0 0x260115"
#define APIJUNGFRAU "0.0.0 0x250909" #define APIJUNGFRAU "0.0.0 0x250909"
#define APIMYTHEN3 "0.0.0 0x260114" #define APIMYTHEN3 "0.0.0 0x260114"

View File

@@ -234,6 +234,11 @@ def loadConfig(name, rx_hostname = 'localhost', settingsdir = None, log_file_fp
d.powerchip = 1 d.powerchip = 1
if name == "xilinx_ctb": if name == "xilinx_ctb":
d.v_a = 1200
d.v_b = 1200
d.v_c = 1200
d.v_d = 1200
d.v_io = 1200
d.configureTransceiver() d.configureTransceiver()
if settingsdir is not None and name in ['eiger', 'mythen3']: if settingsdir is not None and name in ['eiger', 'mythen3']: