diff --git a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer index 34fc895ae..0ec3f81c0 100755 Binary files a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer and b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer differ diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c index e7f914ca1..9d52ea724 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c @@ -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() { diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h index ab899fdb9..74aedc810 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorServer_defs.h @@ -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" diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index e3f44e673..0f4186a8d 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -381,7 +381,16 @@ void setDAC(enum DACINDEX ind, int val, int mV); 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(); @@ -395,16 +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 getMinPowerValue(enum DACINDEX ind); -int isPowerValid(enum DACINDEX ind, int val); -int getPower(); -int setPower(enum DACINDEX ind, int val); #endif #if defined(MYTHEN3D) || defined(GOTTHARD2D) || defined(XILINX_CHIPTESTBOARDD) diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 2704fffd1..c44abeede 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -1283,48 +1283,14 @@ 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 { -#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 + } else { + ret = setPower(serverDacIndex, val, mess); } } if (ret == OK) { - retval = getPower(serverDacIndex); + ret = getPower(serverDacIndex, &retval, mess); LOG(logDEBUG1, ("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); } break; @@ -1401,9 +1367,9 @@ 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 diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/bin/xilinx_ctbDetectorServer_developer b/slsDetectorServers/xilinx_ctbDetectorServer/bin/xilinx_ctbDetectorServer_developer index 1f972aca2..78bc7052b 100755 Binary files a/slsDetectorServers/xilinx_ctbDetectorServer/bin/xilinx_ctbDetectorServer_developer and b/slsDetectorServers/xilinx_ctbDetectorServer/bin/xilinx_ctbDetectorServer_developer differ diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c index a3f56544d..92b4bdfb4 100644 --- a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c @@ -414,13 +414,21 @@ void setupDetector() { LOG(logINFOBLUE, ("Powering down all dacs\n")); 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")); for (int idac = NDAC_ONLY; idac < NDAC; ++idac) { if (idac == D_PWR_EMPTY) continue; - setPower(idac, 0); + initError = setPower(idac, 0, initErrorMessage); + if (initError == FAIL) + return; } resetFlow(); @@ -1205,8 +1213,8 @@ int getDAC(enum DACINDEX ind, int mV) { return dacValues[ind]; } // convert dac units to mV - int voltage = dacToVoltage(dacValues[ind]); - if (voltage == -1) { + int voltage = -1; + 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; @@ -1218,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; @@ -1251,156 +1251,194 @@ 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 getMinPowerValue(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; +void powerEnable(int on, int pwrIndex) { + uint32_t addr = CTRL_REG; + uint32_t mask = (1 << pwrIndex); + + 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)); } - 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; - } +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); - int min = getMinPowerValue(ind); - // check vlimit (already checked at funcs.c) + // 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) { - LOG(logERROR, - ("Invalid value of %d mV for Power %s. Exceeds vLimit of %d mV\n", - val, powerNames[pwrIndex], vLimit)); - return 0; + 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; } - // 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; + // 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 1; + return OK; } -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 mask = (1 << bitOffset); - if (!(bus_r(addr) & mask)) - return 0; - } - +int getPower(enum DACINDEX ind, int *retval, char *mess) { + *retval = -1; char *powerNames[] = {PWR_NAMES}; - int pwrIndex = (int)(ind - D_PWR_D); - int min = getMinPowerValue(ind); - // 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; + } + + // 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 %s!\n", powerNames[pwrIndex])); - 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; } // get dac in mV - int retval = -1; - ConvertToDifferentRange(LTC2620_D_GetMaxInput(), LTC2620_D_GetMinInput(), - min, POWER_RGLTR_MAX, dacValues[ind], &retval); + if (dacToVoltage_PowerRegulators(pwrIndex, dacValues[ind], retval, mess) == + FAIL) + return FAIL; - return retval; + return OK; } -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); - +int setPower(enum DACINDEX ind, int val, char *mess) { char *powerNames[] = {PWR_NAMES}; - int pwrIndex = (int)(ind - D_PWR_D); - int min = getMinPowerValue(ind); + + // 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)); - // Switch off power enable - LOG(logDEBUG1, ("\tSwitching off power enable\n")); - bus_w(addr, bus_r(addr) & ~(mask)); + powerEnable(0, pwrIndex); if (val > 0) { - // convert voltage to dac + // convert mV to dac value 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)); + if (voltageToDac_PowerRegulators(pwrIndex, val, &dacval, mess) == FAIL) return FAIL; - } // set dac value - LOG(logINFO, ("\tSetting DAC %s: %d mV (%d dac)\n", - powerNames[pwrIndex], val, dacval)); + LOG(logINFO, ("\tSetting %s: %d mV (%d dac)\n", powerNames[pwrIndex], + val, dacval)); if (LTC2620_D_WriteDACValue((int)ind, dacval, powerNames[pwrIndex]) == - FAIL) + 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; - // Switch on power enable - LOG(logDEBUG1, ("\tSwitching on power enable for Power %s\n", - powerNames[pwrIndex])); - bus_w(addr, bus_r(addr) | mask); + powerEnable(1, pwrIndex); } return OK; diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorServer_defs.h index 93c5a0bee..8619bd5db 100644 --- a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorServer_defs.h @@ -119,7 +119,15 @@ enum DACINDEX { 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 */ // For arm has to be multiple of 16 diff --git a/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp b/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp index 23cb1eb03..57a0b279d 100644 --- a/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp +++ b/slsDetectorSoftware/tests/Caller/test-Caller-chiptestboard.cpp @@ -1060,9 +1060,9 @@ TEST_CASE("v_abcd", "[.cmdcall]") { if (det_type == defs::XILINX_CHIPTESTBOARD && det.isVirtualDetectorServer().tsquash( "inconsistent virtual values")) { - // prev value for power regulators should have been 0 - // as they are only touched in this test - REQUIRE(prev_val.squash(-1) == 0); + // 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)); } diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index 97dd8899c..3ca4b2b75 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -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 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 0x260114" +#define APIXILINXCTB "0.0.0 0x260115" #define APIJUNGFRAU "0.0.0 0x250909" #define APIMYTHEN3 "0.0.0 0x260114" diff --git a/tests/scripts/utils_for_test.py b/tests/scripts/utils_for_test.py index bff86f886..80b3f2b47 100644 --- a/tests/scripts/utils_for_test.py +++ b/tests/scripts/utils_for_test.py @@ -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']: