mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-01-16 00:14:37 +01:00
Compare commits
6 Commits
fix/setbit
...
dev/xilinx
| Author | SHA1 | Date | |
|---|---|---|---|
| 0a69516459 | |||
| 0aab505645 | |||
| ae793af7b9 | |||
| c04e8e0beb | |||
| 3619577b69 | |||
| c09f92b043 |
Binary file not shown.
@@ -1238,9 +1238,7 @@ void setDAC(enum DACINDEX ind, int val, int mV) {
|
||||
// convert to dac units
|
||||
else if (LTC2620_VoltageToDac(val, &dacval) == OK) {
|
||||
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;
|
||||
#endif
|
||||
}
|
||||
@@ -1259,12 +1257,6 @@ int getDAC(enum DACINDEX ind, int mV) {
|
||||
|
||||
int getMaxDacSteps() { return LTC2620_GetMaxNumSteps(); }
|
||||
|
||||
int dacToVoltage(int dac) {
|
||||
int val;
|
||||
LTC2620_DacToVoltage(dac, &val);
|
||||
return val;
|
||||
}
|
||||
|
||||
int checkVLimitCompliant(int mV) {
|
||||
if (vLimit > 0 && mV > vLimit)
|
||||
return FAIL;
|
||||
@@ -1352,7 +1344,13 @@ int getVChipToSet(enum DACINDEX ind, int val) {
|
||||
for (int ipwr = 0; ipwr < NPWR - 1; ++ipwr) {
|
||||
|
||||
// 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 (ipwr == adcIndex) {
|
||||
@@ -1378,6 +1376,42 @@ int getVChipToSet(enum DACINDEX ind, int val) {
|
||||
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) {
|
||||
switch (ind) {
|
||||
case V_PWR_IO:
|
||||
@@ -1414,46 +1448,103 @@ int getADCIndexFromDACIndex(enum DACINDEX ind) {
|
||||
}
|
||||
}
|
||||
|
||||
int isPowerValid(enum DACINDEX ind, int val) {
|
||||
int min = (ind == D_PWR_IO) ? VIO_MIN_MV : POWER_RGLTR_MIN;
|
||||
void powerEnable(int on, int pwrIndex) {
|
||||
uint32_t addr = POWER_REG;
|
||||
int offset = POWER_ENBL_VLTG_RGLTR_OFST + pwrIndex;
|
||||
uint32_t mask = (1 << offset);
|
||||
|
||||
// not power_rgltr_max because it is allowed only upto vchip max - 200
|
||||
if (val != 0 && (val != LTC2620_GetPowerDownValue()) &&
|
||||
(val < min || val > (VCHIP_MAX_MV - VCHIP_POWER_INCRMNT))) {
|
||||
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));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int getPower(enum DACINDEX ind) {
|
||||
// validate index & get adc index
|
||||
int adcIndex = getADCIndexFromDACIndex(ind);
|
||||
if (adcIndex == -1) {
|
||||
return -1;
|
||||
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
|
||||
int min = pwrIndex == V_PWR_IO ? VIO_MIN_MV : POWER_RGLTR_MIN;
|
||||
int max = VCHIP_MAX_MV - VCHIP_POWER_INCRMNT;
|
||||
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 OK;
|
||||
}
|
||||
|
||||
int getPower(enum DACINDEX ind, int *retval, char *mess) {
|
||||
*retval = -1;
|
||||
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;
|
||||
}
|
||||
|
||||
// powered enable off
|
||||
{
|
||||
uint32_t addr = POWER_REG;
|
||||
uint32_t offset = POWER_ENBL_VLTG_RGLTR_OFST + adcIndex;
|
||||
uint32_t mask = (1 << offset);
|
||||
if (!(bus_r(addr) & mask))
|
||||
return 0;
|
||||
if (getPowerEnable(pwrIndex) == 0) {
|
||||
*retval = 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
// not set yet
|
||||
// dac value not set by user yet
|
||||
if (dacValues[ind] == -1) {
|
||||
LOG(logERROR,
|
||||
("Power enabled, but unknown dac value for power index %d!", ind));
|
||||
return -1;
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Power %s not initialized to a value yet (other than 0). "
|
||||
"Cannot get value.\n",
|
||||
powerNames[pwrIndex]);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// dac powered off
|
||||
// dac powered down
|
||||
if (dacValues[ind] == LTC2620_GetPowerDownValue()) {
|
||||
LOG(logWARNING,
|
||||
("Power %d enabled, dac value %d, voltage at minimum or 0\n", ind,
|
||||
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
|
||||
@@ -1461,100 +1552,100 @@ int getPower(enum DACINDEX ind) {
|
||||
// tried to get a power regulator value
|
||||
if (dacValues[D_PWR_CHIP] == -1 ||
|
||||
dacValues[D_PWR_CHIP] == LTC2620_GetPowerDownValue()) {
|
||||
LOG(logERROR, ("Cannot read power regulator %d (vchip not set)."
|
||||
"Set a power regulator, which will also set vchip.\n"));
|
||||
return -1;
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Power %s cannot be read as vchip is not set. Set a power "
|
||||
"regulator first, which will also set vchip.\n",
|
||||
powerNames[pwrIndex]);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// convert dac to voltage
|
||||
int retval = -1;
|
||||
ConvertToDifferentRange(LTC2620_GetMaxInput(), LTC2620_GetMinInput(),
|
||||
POWER_RGLTR_MIN, POWER_RGLTR_MAX, dacValues[ind],
|
||||
&retval);
|
||||
return retval;
|
||||
// get dac in mV
|
||||
if (dacToVoltage_PowerRegulators(pwrIndex, dacValues[ind], retval, mess) ==
|
||||
FAIL)
|
||||
return FAIL;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void setPower(enum DACINDEX ind, int val) {
|
||||
// validate index & get adc index
|
||||
int adcIndex = getADCIndexFromDACIndex(ind);
|
||||
if (adcIndex == -1) {
|
||||
return;
|
||||
int setPower(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;
|
||||
}
|
||||
|
||||
uint32_t addr = POWER_REG;
|
||||
uint32_t offset = POWER_ENBL_VLTG_RGLTR_OFST + adcIndex;
|
||||
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;
|
||||
}
|
||||
|
||||
// get vchip to set vchip (calculated now before switching off power
|
||||
// enable)
|
||||
int vchip = getVChipToSet(ind, val);
|
||||
LOG(logDEBUG1, ("Vchip to set: %d\n", vchip));
|
||||
// index problem of vchip calculation problem
|
||||
if (vchip == -1)
|
||||
return;
|
||||
|
||||
// Switch off power enable
|
||||
LOG(logDEBUG1, ("Switching off power enable\n"));
|
||||
bus_w(addr, bus_r(addr) & ~(mask));
|
||||
|
||||
// power down dac
|
||||
LOG(logDEBUG1, ("Powering off P%d (DAC %d)\n", adcIndex, ind));
|
||||
setDAC(ind, LTC2620_GetPowerDownValue(), 0);
|
||||
|
||||
// set vchip
|
||||
setVchip(vchip);
|
||||
if (getVchip() != vchip) {
|
||||
LOG(logERROR, ("Weird, Could not set vchip. Set %d, read %d\n.",
|
||||
vchip, getVchip()));
|
||||
return;
|
||||
}
|
||||
|
||||
//(power off is anyway done with power enable)
|
||||
if (val == 0)
|
||||
val = LTC2620_GetPowerDownValue();
|
||||
|
||||
// convert it to dac (power off is anyway done with power enable)
|
||||
if (val != LTC2620_GetPowerDownValue()) {
|
||||
LOG(logDEBUG1, ("Convert Power of %d mV to dac units\n", val));
|
||||
|
||||
int dacval = -1;
|
||||
// convert voltage to dac
|
||||
if (ConvertToDifferentRange(
|
||||
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
|
||||
LOG(logINFO, ("Setting P%d (DAC %d): %d dac (%d mV)\n", adcIndex,
|
||||
ind, dacval, val));
|
||||
setDAC(ind, dacval, 0);
|
||||
|
||||
// to be sure of valid conversion
|
||||
if (dacval >= 0) {
|
||||
LOG(logDEBUG1, ("Switching on power enable\n"));
|
||||
bus_w(addr, bus_r(addr) | mask);
|
||||
}
|
||||
}
|
||||
if (isPowerValid(ind, val, mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
LOG(logINFO, ("Setting Power %s to %d mV\n", powerNames[pwrIndex], val));
|
||||
|
||||
// get vchip to set vchip (calculated now before switching off power
|
||||
// enable)
|
||||
int vchip = getVChipToSet(ind, val);
|
||||
LOG(logDEBUG1, ("Vchip to set: %d\n", vchip));
|
||||
// index issue of vchip calculation
|
||||
if (vchip == -1) {
|
||||
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;
|
||||
}
|
||||
|
||||
powerEnable(0, pwrIndex);
|
||||
|
||||
// power down dac
|
||||
LOG(logDEBUG1, ("Powering off %s\n", powerNames[pwrIndex]));
|
||||
setDAC(ind, LTC2620_GetPowerDownValue(), 0);
|
||||
|
||||
// set vchip
|
||||
setVchip(vchip);
|
||||
if (getVchip() != vchip) {
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Could not set power %s. Tried to set vchip to %d mV, read %d "
|
||||
"mV\n.",
|
||||
powerNames[pwrIndex], vchip, getVchip());
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
//(power off is anyway done with power enable)
|
||||
if (val == 0)
|
||||
val = LTC2620_GetPowerDownValue();
|
||||
|
||||
// convert it to dac (power off is anyway done with power enable)
|
||||
if (val != LTC2620_GetPowerDownValue()) {
|
||||
|
||||
// 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));
|
||||
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;
|
||||
}
|
||||
|
||||
powerEnable(1, pwrIndex);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void powerOff() {
|
||||
|
||||
@@ -147,6 +147,8 @@ enum ADCINDEX {
|
||||
S_ADC7,
|
||||
S_TMP
|
||||
};
|
||||
#define PWR_NAMES "VIO", "VA", "VB", "VC", "VD"
|
||||
|
||||
enum DACINDEX {
|
||||
D0,
|
||||
D1,
|
||||
@@ -173,5 +175,6 @@ enum DACINDEX {
|
||||
D_PWR_A,
|
||||
D_PWR_IO
|
||||
};
|
||||
|
||||
enum CLKINDEX { RUN_CLK, ADC_CLK, SYNC_CLK, DBIT_CLK, NUM_CLOCKS };
|
||||
#define CLK_NAMES "run", "adc", "sync", "dbit"
|
||||
|
||||
Binary file not shown.
@@ -472,8 +472,7 @@ void setupDetector() {
|
||||
// hv
|
||||
DAC6571_SetDefines(HV_HARD_MAX_VOLTAGE, HV_DRIVER_FILE_NAME);
|
||||
// dacs
|
||||
LTC2620_D_SetDefines(DAC_MIN_MV, DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC, 0,
|
||||
"");
|
||||
LTC2620_D_SetDefines(DAC_MIN_MV, DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC, 0);
|
||||
// on chip dacs
|
||||
ASIC_Driver_SetDefines(ONCHIP_DAC_DRIVER_FILE_NAME);
|
||||
setTimingSource(DEFAULT_TIMING_SOURCE);
|
||||
|
||||
Binary file not shown.
@@ -485,8 +485,7 @@ void setupDetector() {
|
||||
// hv
|
||||
DAC6571_SetDefines(HV_HARD_MAX_VOLTAGE, HV_DRIVER_FILE_NAME);
|
||||
// dac
|
||||
LTC2620_D_SetDefines(DAC_MIN_MV, DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC, 0,
|
||||
"");
|
||||
LTC2620_D_SetDefines(DAC_MIN_MV, DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC, 0);
|
||||
|
||||
resetCore();
|
||||
resetPeripheral();
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
void LTC2620_D_SetDefines(int hardMinV, int hardMaxV, char *driverfname,
|
||||
int numdacs, int numpowers,
|
||||
char *powerdownDriverfname);
|
||||
int numdacs, int numpowers);
|
||||
int LTC2620_D_GetMaxNumSteps();
|
||||
int LTC2620_D_GetPowerDownValue();
|
||||
int LTC2620_D_GetMinInput();
|
||||
@@ -28,14 +27,13 @@ int LTC2620_D_VoltageToDac(int voltage, int *dacval);
|
||||
*/
|
||||
int LTC2620_D_DacToVoltage(int dacval, int *voltage);
|
||||
|
||||
/** for all dacs including power regulators to write dac value to file */
|
||||
int LTC2620_D_WriteDACValue(int dacnum, int dacvalue, char *dacname);
|
||||
|
||||
/**
|
||||
* Set value
|
||||
* @param dacnum dac index
|
||||
* @param val value to set
|
||||
* @param mV 1 for mv, else 0
|
||||
* @paam dacname dac name
|
||||
* @param dacval pointer to dac value
|
||||
* @return OK or FAIL
|
||||
* Only for DACs (not power regulators) to validate indices and convert values
|
||||
* to dac units if needed
|
||||
* @param dacval if val is in mV, returns dac units set
|
||||
*/
|
||||
int LTC2620_D_SetDACValue(int dacnum, int val, int mV, char *dacname,
|
||||
int *dacval);
|
||||
@@ -373,13 +373,24 @@ int getOnChipDAC(enum ONCHIP_DACINDEX ind, int chipIndex);
|
||||
void setDAC(enum DACINDEX ind, int val, int mV, int counterEnableCheck);
|
||||
void setGeneralDAC(enum DACINDEX ind, int val, int mV);
|
||||
void setVthDac(int index, int enable);
|
||||
#elif defined(XILINX_CHIPTESTBOARDD)
|
||||
int setDAC(enum DACINDEX ind, int val, int mV);
|
||||
#else
|
||||
void setDAC(enum DACINDEX ind, int val, int mV);
|
||||
#endif
|
||||
int getDAC(enum DACINDEX ind, int mV);
|
||||
int getMaxDacSteps();
|
||||
#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 checkVLimitDacCompliant(int dac);
|
||||
int getVLimit();
|
||||
@@ -393,15 +404,11 @@ void setVchip(int val);
|
||||
int getVChipToSet(enum DACINDEX ind, int val);
|
||||
int getDACIndexFromADCIndex(enum ADCINDEX ind);
|
||||
int getADCIndexFromDACIndex(enum DACINDEX ind);
|
||||
int isPowerValid(enum DACINDEX ind, int val);
|
||||
int getPower();
|
||||
void setPower(enum DACINDEX ind, int val);
|
||||
|
||||
void powerOff();
|
||||
#elif XILINX_CHIPTESTBOARDD
|
||||
int getPwrIndex(enum DACINDEX ind);
|
||||
int getBitOffsetFromDACIndex(enum DACINDEX ind);
|
||||
int isPowerValid(enum DACINDEX ind, int val);
|
||||
int getPower();
|
||||
void setPower(enum DACINDEX ind, int val);
|
||||
#endif
|
||||
|
||||
#if defined(MYTHEN3D) || defined(GOTTHARD2D) || defined(XILINX_CHIPTESTBOARDD)
|
||||
|
||||
@@ -3,7 +3,13 @@
|
||||
#include "LTC2620_Driver.h"
|
||||
#include "clogger.h"
|
||||
#include "common.h"
|
||||
|
||||
// to include power down file name suffix directly
|
||||
#ifdef XILINX_CHIPTESTBOARDD
|
||||
#include "slsDetectorServer_defs.h"
|
||||
#else
|
||||
#include "sls/sls_detector_defs.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -17,13 +23,11 @@
|
||||
int LTC2620_D_HardMinVoltage = 0;
|
||||
int LTC2620_D_HardMaxVoltage = 0;
|
||||
char LTC2620_D_DriverFileName[MAX_STR_LENGTH];
|
||||
char LTC2620_D_PowerDownDriverFileName[MAX_STR_LENGTH];
|
||||
int LTC2620_D_NumDacs = 0;
|
||||
int LTC2620_D_NumDacsOnly = 0;
|
||||
|
||||
void LTC2620_D_SetDefines(int hardMinV, int hardMaxV, char *driverfname,
|
||||
int numdacs, int numpowers,
|
||||
char *powerdownDriverfname) {
|
||||
int numdacs, int numpowers) {
|
||||
LOG(logINFOBLUE,
|
||||
("Configuring DACs (LTC2620) to %s\n\t (numdacs:%d, hard min:%d, hard "
|
||||
"max: %dmV)\n",
|
||||
@@ -32,8 +36,6 @@ void LTC2620_D_SetDefines(int hardMinV, int hardMaxV, char *driverfname,
|
||||
LTC2620_D_HardMaxVoltage = hardMaxV;
|
||||
memset(LTC2620_D_DriverFileName, 0, MAX_STR_LENGTH);
|
||||
strcpy(LTC2620_D_DriverFileName, driverfname);
|
||||
memset(LTC2620_D_PowerDownDriverFileName, 0, MAX_STR_LENGTH);
|
||||
strcpy(LTC2620_D_PowerDownDriverFileName, powerdownDriverfname);
|
||||
LTC2620_D_NumDacs = numdacs;
|
||||
LTC2620_D_NumDacsOnly = numdacs - numpowers;
|
||||
}
|
||||
@@ -58,9 +60,8 @@ int LTC2620_D_DacToVoltage(int dacval, int *voltage) {
|
||||
LTC2620_D_HardMaxVoltage, dacval, voltage);
|
||||
}
|
||||
|
||||
int LTC2620_D_SetDACValue(int dacnum, int val, int mV, char *dacname,
|
||||
int *dacval) {
|
||||
LOG(logDEBUG1, ("dacnum:%d, val:%d, ismV:%d\n", dacnum, val, mV));
|
||||
int LTC2620_D_WriteDACValue(int dacnum, int dacvalue, char *dacname) {
|
||||
LOG(logDEBUG1, ("dacnum:%d, val:%d\n", dacnum, dacvalue));
|
||||
|
||||
// validate index
|
||||
if (dacnum < 0 || dacnum >= LTC2620_D_NumDacs) {
|
||||
@@ -69,98 +70,125 @@ int LTC2620_D_SetDACValue(int dacnum, int val, int mV, char *dacname,
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// validate set
|
||||
if (val < 0 && val != LTC2620_D_PWR_DOWN_VAL)
|
||||
// validate max value
|
||||
if (dacvalue > LTC2620_D_MAX_DAC_VAL) {
|
||||
LOG(logERROR,
|
||||
("Dac %d %s: Invalid dac value %d\n", dacnum, dacname, dacvalue));
|
||||
return FAIL;
|
||||
|
||||
int ret = OK;
|
||||
*dacval = val;
|
||||
#ifndef VIRTUAL
|
||||
char fnameFormat[MAX_STR_LENGTH];
|
||||
memset(fnameFormat, 0, MAX_STR_LENGTH);
|
||||
strcpy(fnameFormat, LTC2620_D_DriverFileName);
|
||||
#endif
|
||||
|
||||
// power down dac (different file name)
|
||||
if (val == LTC2620_D_PWR_DOWN_VAL) {
|
||||
#if defined(XILINX_CHIPTESTBOARDD) && !defined(VIRTUAL)
|
||||
LOG(logINFO, ("Powering down DAC %2d [%-6s] \n", dacnum, dacname));
|
||||
strcpy(fnameFormat, LTC2620_D_PowerDownDriverFileName);
|
||||
#endif
|
||||
}
|
||||
|
||||
// proper value to set
|
||||
else {
|
||||
// convert to dac or get mV value
|
||||
int dacmV = val;
|
||||
if (mV) {
|
||||
ret = LTC2620_D_VoltageToDac(val, dacval);
|
||||
}
|
||||
|
||||
// mV only for print out (dont convert to mV for power regulators)
|
||||
else if (val >= 0 && dacnum < LTC2620_D_NumDacsOnly) {
|
||||
// do not convert power down dac val
|
||||
ret = LTC2620_D_DacToVoltage(val, &dacmV);
|
||||
}
|
||||
|
||||
// conversion out of bounds
|
||||
if (ret == FAIL) {
|
||||
LOG(logERROR, ("Setting Dac %d %s is out of bounds\n", dacnum,
|
||||
(mV ? "mV" : "dac units")));
|
||||
// validate negative values
|
||||
if (dacvalue < 0) {
|
||||
// dacs only: allow power down value (-100)
|
||||
if ((dacnum < LTC2620_D_NumDacsOnly &&
|
||||
dacvalue != LTC2620_D_PWR_DOWN_VAL) ||
|
||||
// power regulators: allow no negative values
|
||||
(dacnum >= LTC2620_D_NumDacsOnly)) {
|
||||
LOG(logERROR, ("Dac %d %s: Invalid dac value %d\n", dacnum, dacname,
|
||||
dacvalue));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// print and set
|
||||
#ifdef XILINX_CHIPTESTBOARDD
|
||||
if (*dacval >= 0) {
|
||||
// also print mV
|
||||
if (dacnum < LTC2620_D_NumDacsOnly) {
|
||||
LOG(logINFO, ("Setting DAC %2d [%-6s] : %d dac (%d mV)\n",
|
||||
dacnum, dacname, *dacval, dacmV));
|
||||
}
|
||||
// do not print mV for power regulators
|
||||
else {
|
||||
LOG(logINFO, ("Setting Power DAC%2d [%-6s] : %d dac \n", dacnum,
|
||||
dacname, *dacval));
|
||||
}
|
||||
}
|
||||
#else
|
||||
if ((*dacval >= 0) || (*dacval == LTC2620_D_PWR_DOWN_VAL)) {
|
||||
LOG(logINFO, ("Setting DAC %2d [%-12s] : %d dac (%d mV)\n", dacnum,
|
||||
dacname, *dacval, dacmV));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// set in file
|
||||
#ifndef VIRTUAL
|
||||
// print info
|
||||
if (dacvalue == LTC2620_D_PWR_DOWN_VAL) {
|
||||
LOG(logDEBUG, ("\tPowering down DAC %2d [%-6s] \n", dacnum, dacname));
|
||||
} else {
|
||||
LOG(logINFO, ("\tSetting DAC %2d [%-6s] to %d dac units\n", dacnum,
|
||||
dacname, dacvalue));
|
||||
}
|
||||
|
||||
#ifdef VIRTUAL
|
||||
return OK;
|
||||
#endif
|
||||
|
||||
// file name
|
||||
char fname[MAX_STR_LENGTH];
|
||||
memset(fname, 0, MAX_STR_LENGTH);
|
||||
snprintf(fname, MAX_STR_LENGTH, "%s%d", LTC2620_D_DriverFileName, dacnum);
|
||||
#ifdef XILINX_CHIPTESTBOARDD
|
||||
sprintf(fname, fnameFormat, dacnum);
|
||||
#else
|
||||
sprintf(fname, "%s%d", fnameFormat, dacnum);
|
||||
// different file for power down
|
||||
if (dacvalue == LTC2620_D_PWR_DOWN_VAL) {
|
||||
snprintf(fname, MAX_STR_LENGTH, "%s%d%s", LTC2620_D_DriverFileName,
|
||||
dacnum, DAC_POWERDOWN_DRIVER_FILE_SUFFIX);
|
||||
}
|
||||
#endif
|
||||
LOG(logDEBUG1, ("fname %s\n", fname));
|
||||
LOG(logINFORED, ("fname %s\n", fname));
|
||||
|
||||
// open file
|
||||
FILE *fd = fopen(fname, "w");
|
||||
if (fd == NULL) {
|
||||
LOG(logERROR, ("Could not open file %s for writing to set dac %d\n",
|
||||
fname, dacnum));
|
||||
LOG(logERROR,
|
||||
("Could not open file %s for writing to set dac %d [%s] \n", fname,
|
||||
dacnum, dacname));
|
||||
return FAIL;
|
||||
}
|
||||
// convert to string, add 0 and write to file
|
||||
#ifdef XILINX_CHIPTESTBOARDD
|
||||
// not changing *dacval from -100 (cant write -100 to file: invalid arg)
|
||||
int writeValue = *dacval;
|
||||
if (writeValue == LTC2620_D_PWR_DOWN_VAL)
|
||||
writeValue = 1;
|
||||
fprintf(fd, "%d\n", writeValue);
|
||||
|
||||
// write to file
|
||||
#ifndef XILINX_CHIPTESTBOARDD
|
||||
fprintf(fd, "%d\n", dacvalue);
|
||||
#else
|
||||
fprintf(fd, "%d\n", *dacval);
|
||||
// cant write -100 to file: invalid arg
|
||||
if (dacvalue == LTC2620_D_PWR_DOWN_VAL) {
|
||||
fprintf(fd, "1\n");
|
||||
} else {
|
||||
fprintf(fd, "%d\n", dacvalue);
|
||||
}
|
||||
#endif
|
||||
fclose(fd);
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int LTC2620_D_SetDACValue(int dacnum, int val, int mV, char *dacname,
|
||||
int *dacval) {
|
||||
LOG(logDEBUG1,
|
||||
("dacnum:%d (%s), val:%d, ismV:%d\n", dacnum, dacname, val, mV));
|
||||
|
||||
// invalid index
|
||||
if (dacnum >= LTC2620_D_NumDacs) {
|
||||
LOG(logERROR, ("Dac index %d is out of bounds (0 to %d)\n", dacnum,
|
||||
LTC2620_D_NumDacs - 1));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (mV && dacnum >= LTC2620_D_NumDacsOnly) {
|
||||
LOG(logERROR, ("Cannot convert to dac units for power regulator %d %s "
|
||||
"here. Expecting dac units here.\n",
|
||||
dacnum, dacname));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
*dacval = val;
|
||||
if (val == LTC2620_D_GetPowerDownValue()) {
|
||||
LOG(logINFO, ("\tPowering down DAC %2d [%-6s] \n", dacnum, dacname));
|
||||
} else {
|
||||
|
||||
// invalid negative value
|
||||
if (val < 0) {
|
||||
LOG(logERROR, ("Invalid value %d for dac[%d - %s]\n", val,
|
||||
(int)dacnum, dacname));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// convert to dac units or mV (print)
|
||||
if (dacnum < LTC2620_D_NumDacsOnly) {
|
||||
int dacmV = val;
|
||||
int ret = OK;
|
||||
if (mV) {
|
||||
ret = LTC2620_D_VoltageToDac(val, dacval);
|
||||
} else {
|
||||
ret = LTC2620_D_DacToVoltage(val, &dacmV);
|
||||
}
|
||||
// conversion out of bounds
|
||||
if (ret == FAIL) {
|
||||
LOG(logERROR, ("Setting Dac %d %s is out of bounds\n", dacnum,
|
||||
(mV ? "mV" : "dac units")));
|
||||
return FAIL;
|
||||
}
|
||||
LOG(logINFO, ("Setting DAC %2d [%-6s] : %d dac (%d mV)\n", dacnum,
|
||||
dacname, *dacval, dacmV));
|
||||
}
|
||||
}
|
||||
|
||||
return LTC2620_D_WriteDACValue(dacnum, *dacval, dacname);
|
||||
}
|
||||
|
||||
@@ -1283,32 +1283,15 @@ int validateAndSetDac(enum dacIndex ind, int val, int mV) {
|
||||
"exceeds voltage limit %d.\n",
|
||||
ind, getVLimit());
|
||||
LOG(logERROR, (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 {
|
||||
setPower(serverDacIndex, val);
|
||||
} else {
|
||||
ret = setPower(serverDacIndex, val, mess);
|
||||
}
|
||||
}
|
||||
if (ret == OK) {
|
||||
retval = getPower(serverDacIndex);
|
||||
LOG(logDEBUG1, ("Power regulator(%d): %d\n", ind, retval));
|
||||
validate(&ret, mess, val, retval, "set power regulator", DEC);
|
||||
ret = getPower(serverDacIndex, &retval, mess);
|
||||
LOG(logDEBUG1,
|
||||
("Power regulator(%d): %d\n", serverDacIndex, retval));
|
||||
validate(&ret, mess, val, retval, "set/get power regulator", DEC);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@@ -1384,19 +1367,44 @@ int validateAndSetDac(enum dacIndex ind, int val, int mV) {
|
||||
checkVLimitDacCompliant(val) == FAIL)) {
|
||||
ret = FAIL;
|
||||
sprintf(mess,
|
||||
"Could not set dac %d to value %d. "
|
||||
"Exceeds voltage limit %d.\n",
|
||||
ind, (mV ? val : dacToVoltage(val)), getVLimit());
|
||||
"Could not set dac %d. "
|
||||
"Exceeds voltage limit %d mV.\n",
|
||||
ind, getVLimit());
|
||||
LOG(logERROR, (mess));
|
||||
} else
|
||||
#endif
|
||||
#ifdef MYTHEN3D
|
||||
// ignore counter enable to force vth dac values
|
||||
setDAC(serverDacIndex, val, mV, 0);
|
||||
#if defined(XILINX_CHIPTESTBOARDD)
|
||||
{
|
||||
if (val != GET_FLAG) {
|
||||
ret = setDAC(serverDacIndex, val, mV);
|
||||
if (ret == FAIL) {
|
||||
sprintf(mess, "Setting dac %d to value %d failed.\n",
|
||||
serverDacIndex, val);
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
}
|
||||
if (ret == OK) {
|
||||
retval = getDAC(serverDacIndex, mV);
|
||||
LOG(logDEBUG1, ("Dac (%d): %d %s\n", serverDacIndex, retval,
|
||||
(mV ? "mV" : "dac units")));
|
||||
if (retval == -1) {
|
||||
ret = FAIL;
|
||||
sprintf(mess, "Could not get dac %d.\n",
|
||||
serverDacIndex);
|
||||
LOG(logERROR, (mess));
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif MYTHEN3D
|
||||
// ignore counter enable to force vth dac values
|
||||
setDAC(serverDacIndex, val, mV, 0);
|
||||
#else
|
||||
setDAC(serverDacIndex, val, mV);
|
||||
#endif
|
||||
|
||||
retval = getDAC(serverDacIndex, mV);
|
||||
LOG(logDEBUG1, ("Dac (%d): %d %s\n", serverDacIndex, retval,
|
||||
(mV ? "mV" : "dac units")));
|
||||
#endif
|
||||
}
|
||||
#ifdef EIGERD
|
||||
if (val != GET_FLAG && getSettings() != UNDEFINED) {
|
||||
|
||||
Binary file not shown.
@@ -404,7 +404,7 @@ void setupDetector() {
|
||||
}
|
||||
|
||||
LTC2620_D_SetDefines(DAC_MIN_MV, DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC,
|
||||
NPWR, DAC_POWERDOWN_DRIVER_FILE_NAME);
|
||||
NPWR);
|
||||
|
||||
// power LTC2620 before talking to it:
|
||||
initError = XILINX_FMC_enable_all(initErrorMessage, MAX_STR_LENGTH);
|
||||
@@ -413,8 +413,22 @@ void setupDetector() {
|
||||
}
|
||||
|
||||
LOG(logINFOBLUE, ("Powering down all dacs\n"));
|
||||
for (int idac = 0; idac < NDAC; ++idac) {
|
||||
setDAC(idac, LTC2620_D_GetPowerDownValue(), 0);
|
||||
for (int idac = 0; idac < NDAC_ONLY; ++idac) {
|
||||
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"));
|
||||
for (int idac = NDAC_ONLY; idac < NDAC; ++idac) {
|
||||
if (idac == D_PWR_EMPTY)
|
||||
continue;
|
||||
initError = setPower(idac, 0, initErrorMessage);
|
||||
if (initError == FAIL)
|
||||
return;
|
||||
}
|
||||
|
||||
resetFlow();
|
||||
@@ -499,29 +513,24 @@ int waitTransceiverReset(char *mess) {
|
||||
#ifdef VIRTUAL
|
||||
void setTransceiverAlignment(int align) {
|
||||
if (align) {
|
||||
bus_w(TRANSCEIVERSTATUS,
|
||||
(bus_r(TRANSCEIVERSTATUS) | RXBYTEISALIGNED_MSK));
|
||||
bus_w(TRANSCEIVERSTATUS2, (bus_r(TRANSCEIVERSTATUS2) | RXLOCKED_MSK));
|
||||
} else {
|
||||
bus_w(TRANSCEIVERSTATUS,
|
||||
(bus_r(TRANSCEIVERSTATUS) & ~RXBYTEISALIGNED_MSK));
|
||||
bus_w(TRANSCEIVERSTATUS2, (bus_r(TRANSCEIVERSTATUS2) & ~RXLOCKED_MSK));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int isTransceiverAligned() {
|
||||
#ifdef VIRTUAL
|
||||
return 1;
|
||||
#endif
|
||||
int times = 0;
|
||||
int retval = bus_r(TRANSCEIVERSTATUS2) & RXLOCKED_MSK;
|
||||
while (retval) {
|
||||
retval = bus_r(TRANSCEIVERSTATUS2) & RXLOCKED_MSK;
|
||||
while (retval == 0u) {
|
||||
times++;
|
||||
usleep(10);
|
||||
if (times == 5)
|
||||
return 1;
|
||||
return 0;
|
||||
retval = bus_r(TRANSCEIVERSTATUS2) & RXLOCKED_MSK;
|
||||
}
|
||||
return retval;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int waitTransceiverAligned(char *mess) {
|
||||
@@ -1151,28 +1160,65 @@ int64_t getMeasurementTime() {
|
||||
|
||||
/* parameters - dac, adc, hv */
|
||||
|
||||
void setDAC(enum DACINDEX ind, int val, int mV) {
|
||||
int setDAC(enum DACINDEX ind, int val, int mV) {
|
||||
char dacName[MAX_STR_LENGTH] = {0};
|
||||
memset(dacName, 0, MAX_STR_LENGTH);
|
||||
sprintf(dacName, "dac%d", (int)ind);
|
||||
|
||||
if (val < 0 && val != LTC2620_D_GetPowerDownValue())
|
||||
return;
|
||||
// invalid index (only dacs, no power regulators)
|
||||
if (ind >= NDAC_ONLY) {
|
||||
LOG(logERROR, ("Invalid DAC index: %d\n", ind));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
LOG(logDEBUG1, ("Setting dac[%d - %s]: %d %s \n", (int)ind, dacName, val,
|
||||
(mV ? "mV" : "dac units")));
|
||||
int dacval = val;
|
||||
if (LTC2620_D_SetDACValue((int)ind, val, mV, dacName, &dacval) == OK)
|
||||
dacValues[ind] = dacval;
|
||||
// ensure vlimit compliance
|
||||
if (val != LTC2620_D_GetPowerDownValue()) {
|
||||
int dacmV = val;
|
||||
if (!mV) {
|
||||
// convert dac units to mV
|
||||
if (LTC2620_D_DacToVoltage(val, &dacmV) == FAIL) {
|
||||
LOG(logERROR, ("Could not convert %d dac units to mV for %s\n",
|
||||
val, dacName));
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
if (checkVLimitCompliant(dacmV) == FAIL) {
|
||||
LOG(logERROR, ("Value %d mV exceeds vLimit of %d mV for "
|
||||
"%s\n",
|
||||
dacmV, vLimit, dacName));
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
// set dac
|
||||
LOG(logINFO, ("Setting dac[%d - %s]: %d %s \n", (int)ind, dacName, val,
|
||||
(mV ? "mV" : "dac units")));
|
||||
int dacval = -1;
|
||||
if (LTC2620_D_SetDACValue((int)ind, val, mV, dacName, &dacval) == FAIL)
|
||||
return FAIL;
|
||||
dacValues[ind] = dacval;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getDAC(enum DACINDEX ind, int mV) {
|
||||
// invalid index (only dacs, no power regulators)
|
||||
if (ind >= NDAC_ONLY) {
|
||||
LOG(logERROR, ("Invalid DAC index: %d\n", ind));
|
||||
return -1;
|
||||
}
|
||||
// get dac in dac units
|
||||
if (!mV) {
|
||||
LOG(logDEBUG1, ("Getting DAC %d : %d dac\n", ind, dacValues[ind]));
|
||||
return dacValues[ind];
|
||||
}
|
||||
// convert dac units to mV
|
||||
int voltage = -1;
|
||||
LTC2620_D_DacToVoltage(dacValues[ind], &voltage);
|
||||
if (LTC2620_D_DacToVoltage(dacValues[ind], &voltage) == FAIL) {
|
||||
LOG(logERROR, ("Could not convert %d dac units to mV for dac %d\n",
|
||||
dacValues[ind], ind));
|
||||
return -1;
|
||||
}
|
||||
LOG(logDEBUG1,
|
||||
("Getting DAC %d : %d dac (%d mV)\n", ind, dacValues[ind], voltage));
|
||||
return voltage;
|
||||
@@ -1180,14 +1226,6 @@ int getDAC(enum DACINDEX ind, int mV) {
|
||||
|
||||
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) {
|
||||
if (vLimit > 0 && mV > vLimit)
|
||||
return FAIL;
|
||||
@@ -1213,149 +1251,197 @@ void setVLimit(int 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) {
|
||||
case D_PWR_IO:
|
||||
return POWER_VIO_OFST;
|
||||
return V_PWR_IO; // same as POWER_VIO_OFST
|
||||
case D_PWR_A:
|
||||
return POWER_VCC_A_OFST;
|
||||
return V_PWR_A; // same as POWER_VCC_A_OFST
|
||||
case D_PWR_B:
|
||||
return POWER_VCC_B_OFST;
|
||||
return V_PWR_B; // same as POWER_VCC_B_OFST
|
||||
case D_PWR_C:
|
||||
return POWER_VCC_C_OFST;
|
||||
return V_PWR_C; // same as POWER_VCC_C_OFST
|
||||
case D_PWR_D:
|
||||
return POWER_VCC_D_OFST;
|
||||
return V_PWR_D; // same as POWER_VCC_D_OFST
|
||||
default:
|
||||
LOG(logERROR,
|
||||
("DAC index %d is not defined to get offset in ctrl register\n",
|
||||
ind));
|
||||
LOG(logERROR, ("DAC index %d is not defined for Power\n", ind));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int isPowerValid(enum DACINDEX ind, int val) {
|
||||
char *powerNames[] = {PWR_NAMES};
|
||||
int pwrIndex = (int)(ind - D_PWR_D);
|
||||
void powerEnable(int on, int pwrIndex) {
|
||||
uint32_t addr = CTRL_REG;
|
||||
uint32_t mask = (1 << pwrIndex);
|
||||
|
||||
int min = POWER_RGLTR_MIN;
|
||||
if (!strcmp(powerNames[pwrIndex], "IO")) {
|
||||
min = VIO_MIN_MV;
|
||||
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));
|
||||
}
|
||||
|
||||
// not power_rgltr_max because it is allowed only upto vchip max - 200
|
||||
if (val != 0 && (val != LTC2620_D_GetPowerDownValue()) &&
|
||||
(val < min || val > POWER_RGLTR_MAX)) {
|
||||
LOG(logERROR,
|
||||
("Invalid value of %d mV for Power V%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) {
|
||||
// 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 mask = (1 << bitOffset);
|
||||
if (!(bus_r(addr) & mask))
|
||||
return 0;
|
||||
}
|
||||
int getPowerEnable(int pwrIndex) {
|
||||
uint32_t mask = (1 << pwrIndex);
|
||||
return (bus_r(CTRL_REG) & mask);
|
||||
}
|
||||
|
||||
int isPowerValid(enum DACINDEX ind, int val, char *mess) {
|
||||
char *powerNames[] = {PWR_NAMES};
|
||||
int pwrIndex = (int)(ind - D_PWR_D);
|
||||
|
||||
// not set yet
|
||||
// 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) {
|
||||
LOG(logERROR,
|
||||
("Unknown dac value for Power V%s!\n", powerNames[pwrIndex]));
|
||||
return -1;
|
||||
}
|
||||
|
||||
// dac powered off
|
||||
if (dacValues[ind] == LTC2620_D_GetPowerDownValue()) {
|
||||
LOG(logWARNING, ("Power V%s enabled, but voltage is at minimum or 0.\n",
|
||||
powerNames[pwrIndex]));
|
||||
return LTC2620_D_GetPowerDownValue();
|
||||
snprintf(mess, MAX_STR_LENGTH,
|
||||
"Power %s not initialized to a value yet (other than 0). "
|
||||
"Cannot get value.\n",
|
||||
powerNames[pwrIndex]);
|
||||
LOG(logERROR, (mess));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// get dac in mV
|
||||
int retval = -1;
|
||||
ConvertToDifferentRange(LTC2620_D_GetMaxInput(), LTC2620_D_GetMinInput(),
|
||||
POWER_RGLTR_MIN, POWER_RGLTR_MAX, dacValues[ind],
|
||||
&retval);
|
||||
if (dacToVoltage_PowerRegulators(pwrIndex, dacValues[ind], retval, mess) ==
|
||||
FAIL)
|
||||
return FAIL;
|
||||
|
||||
return retval;
|
||||
return OK;
|
||||
}
|
||||
|
||||
void setPower(enum DACINDEX ind, int val) {
|
||||
// validate index and get bit offset in ctrl register
|
||||
int bitOffset = getBitOffsetFromDACIndex(ind);
|
||||
if (bitOffset == -1) {
|
||||
return;
|
||||
}
|
||||
uint32_t addr = CTRL_REG;
|
||||
uint32_t mask = (1 << bitOffset);
|
||||
|
||||
if (val == -1)
|
||||
return;
|
||||
|
||||
int setPower(enum DACINDEX ind, int val, char *mess) {
|
||||
char *powerNames[] = {PWR_NAMES};
|
||||
int pwrIndex = (int)(ind - D_PWR_D);
|
||||
LOG(logINFO, ("Setting Power V%s to %d mV\n", powerNames[pwrIndex], val));
|
||||
|
||||
// validate value (already checked at tcp (funcs.c))
|
||||
if (!isPowerValid(ind, val)) {
|
||||
LOG(logERROR, ("Invalid power value for V%s: %d mV\n",
|
||||
powerNames[pwrIndex], val));
|
||||
return;
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Switch off power enable
|
||||
LOG(logDEBUG1, ("Switching off power enable\n"));
|
||||
bus_w(addr, bus_r(addr) & ~(mask));
|
||||
if (isPowerValid(ind, val, mess) == FAIL) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// power down dac
|
||||
LOG(logINFO, ("\tPowering down V%d\n", powerNames[pwrIndex]));
|
||||
setDAC(ind, LTC2620_D_GetPowerDownValue(), 0);
|
||||
LOG(logINFO, ("Setting Power %s to %d mV\n", powerNames[pwrIndex], val));
|
||||
|
||||
//(power off is anyway done with power enable)
|
||||
if (val == 0)
|
||||
val = LTC2620_D_GetPowerDownValue();
|
||||
|
||||
// convert voltage to dac (power off is anyway done with power enable)
|
||||
if (val != LTC2620_D_GetPowerDownValue()) {
|
||||
powerEnable(0, pwrIndex);
|
||||
|
||||
if (val > 0) {
|
||||
// convert mV to dac value
|
||||
int dacval = -1;
|
||||
if (ConvertToDifferentRange(
|
||||
POWER_RGLTR_MIN, POWER_RGLTR_MAX, LTC2620_D_GetMaxInput(),
|
||||
LTC2620_D_GetMinInput(), val, &dacval) == FAIL) {
|
||||
LOG(logERROR,
|
||||
("\tCannot convert Power V%s to dac value. Invalid value of %d "
|
||||
"mV. Is not between "
|
||||
"%d and %d mV\n",
|
||||
powerNames[pwrIndex], val, POWER_RGLTR_MIN, POWER_RGLTR_MAX));
|
||||
return;
|
||||
}
|
||||
if (voltageToDac_PowerRegulators(pwrIndex, val, &dacval, mess) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
// set and power on/ update dac
|
||||
LOG(logINFO, ("Setting Power V%s: %d mV (%d dac)\n",
|
||||
powerNames[pwrIndex], val, dacval));
|
||||
setDAC(ind, dacval, 0);
|
||||
|
||||
// if valid, enable power
|
||||
if (dacval >= 0) {
|
||||
LOG(logDEBUG1, ("Switching on power enable\n"));
|
||||
bus_w(addr, bus_r(addr) | mask);
|
||||
// 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;
|
||||
|
||||
powerEnable(1, pwrIndex);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getADC(enum ADCINDEX ind, int *value) {
|
||||
@@ -1389,7 +1475,7 @@ int getSlowADC(int ichan, int *retval) {
|
||||
#ifndef VIRTUAL
|
||||
char fname[MAX_STR_LENGTH];
|
||||
memset(fname, 0, MAX_STR_LENGTH);
|
||||
sprintf(fname, SLOWADC_DRIVER_FILE_NAME, ichan);
|
||||
sprintf(fname, "%s%d", SLOWADC_DRIVER_FILE_NAME, ichan);
|
||||
LOG(logDEBUG1, ("fname %s\n", fname));
|
||||
|
||||
if (readParameterFromFile(fname, "slow adc", retval) == FAIL) {
|
||||
|
||||
@@ -35,10 +35,10 @@
|
||||
#define DEVICE_NAME_LIST "xilinx-ams", "ad7689", "dac@0", "dac@1", "dac@2"
|
||||
#define DEVICE_TREE_API_FOLDER "/sys/kernel/config/device-tree/overlays/spidr"
|
||||
|
||||
#define DAC_DRIVER_FILE_NAME CURRENT_BOARD_LINKS_FOLDER "/ao%d"
|
||||
#define DAC_POWERDOWN_DRIVER_FILE_NAME CURRENT_BOARD_LINKS_FOLDER "/ao%d_pd"
|
||||
#define SLOWADC_DRIVER_FILE_NAME CURRENT_BOARD_LINKS_FOLDER "/ai%d"
|
||||
#define TEMP_DRIVER_FILE_NAME DEVICE_TREE_DST "0/in_temp7_input"
|
||||
#define DAC_DRIVER_FILE_NAME CURRENT_BOARD_LINKS_FOLDER "/ao"
|
||||
#define DAC_POWERDOWN_DRIVER_FILE_SUFFIX "_pd"
|
||||
#define SLOWADC_DRIVER_FILE_NAME CURRENT_BOARD_LINKS_FOLDER "/ai"
|
||||
#define TEMP_DRIVER_FILE_NAME DEVICE_TREE_DST "0/in_temp7_input"
|
||||
|
||||
#define CONFIG_CHIP_FILE "chip_config_xilinx.txt"
|
||||
#define RESET_CHIP_FILE "reset_chip_xilinx.txt"
|
||||
@@ -119,7 +119,15 @@ enum DACINDEX {
|
||||
D_PWR_C
|
||||
};
|
||||
|
||||
#define PWR_NAMES "D", "_unknown", "IO", "A", "B", "C"
|
||||
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 */
|
||||
// For arm has to be multiple of 16
|
||||
|
||||
@@ -753,10 +753,12 @@ TEST_CASE("v_limit", "[.cmdcall]") {
|
||||
if (det_type == defs::CHIPTESTBOARD ||
|
||||
det_type == defs::XILINX_CHIPTESTBOARD) {
|
||||
auto prev_val = det.getPower(defs::V_LIMIT);
|
||||
auto prev_va = det.getPower(defs::V_POWER_A);
|
||||
{
|
||||
std::ostringstream oss;
|
||||
caller.call("v_limit", {"1500"}, -1, PUT, oss);
|
||||
REQUIRE(oss.str() == "v_limit 1500\n");
|
||||
REQUIRE_THROWS(caller.call("v_a", {"1600"}, -1, PUT, oss));
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
@@ -778,6 +780,7 @@ TEST_CASE("v_limit", "[.cmdcall]") {
|
||||
prev_val[i] = 0;
|
||||
}
|
||||
det.setPower(defs::V_LIMIT, prev_val[i], {i});
|
||||
det.setPower(defs::V_POWER_A, prev_va[i], {i});
|
||||
}
|
||||
} else {
|
||||
REQUIRE_THROWS(caller.call("v_limit", {}, -1, GET));
|
||||
@@ -1053,6 +1056,16 @@ TEST_CASE("v_abcd", "[.cmdcall]") {
|
||||
caller.call(cmds[i], {}, -1, GET, oss2);
|
||||
REQUIRE(oss2.str() == cmds[i] + " 1200\n");
|
||||
}
|
||||
|
||||
if (det_type == defs::XILINX_CHIPTESTBOARD &&
|
||||
det.isVirtualDetectorServer().tsquash(
|
||||
"inconsistent virtual values")) {
|
||||
// prev value for power regulators should have been 1200
|
||||
// (set in config) as they are only touched in this test
|
||||
REQUIRE(prev_val.squash(-1) == 1200);
|
||||
REQUIRE_THROWS(caller.call(cmds[i], {"-100"}, -1, PUT));
|
||||
}
|
||||
|
||||
for (int i = 0; i != det.size(); ++i) {
|
||||
if (det_type == defs::XILINX_CHIPTESTBOARD &&
|
||||
prev_val[i] == -100) {
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
/** API versions */
|
||||
#define APILIB "0.0.0 0x250909"
|
||||
#define APIRECEIVER "0.0.0 0x250822"
|
||||
#define APICTB "0.0.0 0x250922"
|
||||
#define APIGOTTHARD2 "0.0.0 0x250909"
|
||||
#define APICTB "0.0.0 0x260115"
|
||||
#define APIGOTTHARD2 "0.0.0 0x260114"
|
||||
#define APIMOENCH "0.0.0 0x250909"
|
||||
#define APIEIGER "0.0.0 0x250909"
|
||||
#define APIXILINXCTB "0.0.0 0x260106"
|
||||
#define APIXILINXCTB "0.0.0 0x260115"
|
||||
#define APIJUNGFRAU "0.0.0 0x250909"
|
||||
#define APIMYTHEN3 "0.0.0 0x250922"
|
||||
#define APIMYTHEN3 "0.0.0 0x260114"
|
||||
|
||||
@@ -234,6 +234,11 @@ def loadConfig(name, rx_hostname = 'localhost', settingsdir = None, log_file_fp
|
||||
d.powerchip = 1
|
||||
|
||||
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()
|
||||
|
||||
if settingsdir is not None and name in ['eiger', 'mythen3']:
|
||||
|
||||
Reference in New Issue
Block a user