From aeec1204309ba833c61be9a8c9e14c61bd143fc0 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Thu, 5 Feb 2026 16:30:11 +0100 Subject: [PATCH] wip. xilinx --- .../slsDetectorFunctionList.c | 49 +- .../slsDetectorFunctionList.h | 1 + .../slsDetectorFunctionList.c | 514 +++++++++++------- .../slsDetectorFunctionList.h | 24 +- .../slsDetectorServer_defs.h | 5 +- 5 files changed, 353 insertions(+), 240 deletions(-) diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c index 7fe88116e..43c249205 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c @@ -589,6 +589,8 @@ void setupDetector() { DAC_MAX_MV); // has to be before setvchip LTC2620_Disable(); LTC2620_Configure(); + + // dacs only LOG(logINFOBLUE, ("Powering down all dacs\n")); for (int idac = 0; idac < NDAC_ONLY; ++idac) { initError = setDAC(idac, LTC2620_GetPowerDownValue(), 0, initErrorMessage); @@ -596,7 +598,7 @@ void setupDetector() { return; } - // power regulators (set min dac values, still power disabled) + // power regulators LOG(logINFOBLUE, ("Setting power dacs to minimum (power disabled)\n")); for (int idac = NDAC_ONLY; idac < NDAC; ++idac) { initError = initPower(idac, initErrorMessage); @@ -1259,7 +1261,7 @@ int getADCVpp(int mV, int* retval, char* mess) { int validateDAC(enum DACINDEX ind, int val, int mV, char* mess) { // validate index - if (ind < D0 || ind > D_PWR_IO) { + if (ind < 0 || ind >= NDAC) { sprintf(mess, "Could not set DAC %d. Invalid index.\n", ind); LOG(logERROR, (mess)); return FAIL; @@ -1271,7 +1273,8 @@ int validateDAC(enum DACINDEX ind, int val, int mV, char* mess) { LOG(logERROR, (mess)); return FAIL; } - if (ind >= D_PWR_D) { + // power regulators are converted to dacs at setPower with diff conv. + if (ind >= NDAC_ONLY) { sprintf(mess, "Could not set DAC %d. Cannot convert to dac units for power regulator at this stage. Should have been earlier.\n"); LOG(logERROR, (mess)); return FAIL; @@ -1280,9 +1283,9 @@ int validateDAC(enum DACINDEX ind, int val, int mV, char* mess) { // validate min value if (val < 0) { // dacs only: allow power down value (-100) - if ((ind < D_PWR_D && val != LTC2620_GetPowerDownValue()) || + if ((ind < NDAC_ONLY && val != LTC2620_GetPowerDownValue()) || // power regulators: allow no negative values - (ind >= D_PWR_D)) { + (ind >= NDAC_ONLY)) { sprintf(mess, "Could not set DAC %d. Invalid value %d\n", ind, val); LOG(logERROR, (mess)); return FAIL; @@ -1298,7 +1301,7 @@ int validateDAC(enum DACINDEX ind, int val, int mV, char* mess) { return FAIL; } // check vLimit - only dacs, convert to mV - if (vLimit > 0 && ind < PWR_D) { + if (vLimit > 0 && ind < NDAC_ONLY) { int dacmV = 0; if (LTC2620_DacToVoltage(val, &dacmV) == FAIL) { sprintf(mess, "Could not set DAC %d. Could not convert input %d to mV\n", ind, val); @@ -1357,13 +1360,13 @@ int setDAC(enum DACINDEX ind, int val, int mV, char* mess) { int getDAC(enum DACINDEX ind, int mV, int* retval, char* mess) { // validate index - if (ind < D0 || ind > D_PWR_IO) { + if (ind < 0 || ind > NDAC) { sprintf(mess, "Could not get DAC %d. Invalid index.\n", ind); LOG(logERROR, (mess)); return FAIL; } // validate mV - if (mV && ind >= D_PWR_D) { + if (mV && ind >= NDAC_ONLY) { sprintf(mess, "Could not get DAC %d. Cannot convert to dac units for power regulator at this stage. Should have been earlier.\n"); LOG(logERROR, (mess)); return FAIL; @@ -1626,35 +1629,7 @@ int getPower(enum DACINDEX ind, int* retval, char* mess) { return OK; } - // power enabled but not set yet - // should never happen for ctb as one cannot turn on without setting it - // but can be set using just the dac command maybe - if (dacValues[ind] == -1) { - sprintf(mess, "Power enabled, but unknown dac value for %s", powerNames[pwrIndex]); - LOG(logERROR, (mess)); - return FAIL; - } - - // dac powered off - if (dacValues[ind] == LTC2620_GetPowerDownValue()) { - LOG(logWARNING, - ("Power %d enabled, dac value %d, voltage at minimum or 0\n", ind, - LTC2620_GetPowerDownValue())); - *retval = LTC2620_GetPowerDownValue(); - return OK; - } - - // vchip not set - // should not happen (as vchip set to max in the beginning) - // unless user set vchip to power down value (-100) using dac command - // and then tried to get a power regulator value - if (dacValues[D_PWR_CHIP] == -1 || - dacValues[D_PWR_CHIP] == LTC2620_GetPowerDownValue()) { - sprintf(mess, "Cannot read %s (vchip not set). Set a power regulator, which will also set vchip.\n", powerNames[pwrIndex]); - LOG(logERROR, (mess)); - return FAIL; - } - + // to mV if (convertPowerRegDACtoVoltage(pwrIndex, dacValues[ind], retval, mess) == FAIL) return FAIL; diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.h b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.h index 0ea71d3e8..3d81e3778 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.h +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.h @@ -126,6 +126,7 @@ enum detectorSettings getSettings(); int setADCVpp(int val, int mV, char* mess); int getADCVpp(int mV, int* retval, char* mess); +int validateDAC(enum DACINDEX ind, int val, int mV, char* mess); int setDAC(enum DACINDEX ind, int val, int mV, char* mess); int getDAC(enum DACINDEX ind, int mV, int* retval, char* mess); int getVLimit(); diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c index d56724d2d..a302aec04 100644 --- a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.c @@ -406,15 +406,25 @@ void setupDetector() { LTC2620_D_SetDefines(DAC_MIN_MV, DAC_MAX_MV, DAC_DRIVER_FILE_NAME, NDAC, NPWR, DAC_POWERDOWN_DRIVER_FILE_NAME); - // power LTC2620 before talking to it: + // power LTC2620 before talking to it initError = XILINX_FMC_enable_all(initErrorMessage, MAX_STR_LENGTH); if (initError == FAIL) { return; } - + // dacs only 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, initErrorMessage); + if (initError == FAIL) + return; + } + + // power regulators + LOG(logINFOBLUE, ("Setting power dacs to minimum (power disabled)\n")); + for (int idac = NDAC_ONLY; idac < NDAC; ++idac) { + initError = initPower(idac, initErrorMessage); + if (initError == FAIL) + return; } resetFlow(); @@ -1150,84 +1160,133 @@ int64_t getMeasurementTime() { } /* parameters - dac, adc, hv */ - -int setPower(enum DACINDEX ind, int val, int mV, char* mess) { - - serverdacindex - if (checkVLimitCompliant(val) == FAIL) { - sprintf(mess, "Could not set power. Power regulator %d exceeds voltage limit %d.\n", ind, getVLimit()); +int validateDAC(enum DACINDEX ind, int val, int mV, char* mess) { + // validate index + if (ind < 0 || ind >= NDAC) { + sprintf(mess, "Could not set DAC %d. Invalid index.\n", ind); LOG(logERROR, (mess)); return FAIL; } - if (!isPowerValid(ind, val)) { - sprintf(mess, "Could not set power. Power regulator %d should be between %d and %d mV\n", ind, (ind == D_PWR_IO ? VIO_MIN_MV : POWER_RGLTR_MIN), POWER_RGLTR_MAX); - LOG(logERROR, (mess)); - return FAIL; + // validate mV + if (mV) { + if (val == LTC2620_D_GetPowerDownValue()) { + sprintf(mess, "Could not set DAC %d. Cannot use power down value and use 'mV'\n", ind); + LOG(logERROR, (mess)); + return FAIL; + } + // power regulators are converted to dacs at setPower with diff conv. + if (ind >= NDAC_ONLY) { + sprintf(mess, "Could not set DAC %d. Cannot convert to dac units for power regulator at this stage. Should have been earlier.\n"); + LOG(logERROR, (mess)); + return FAIL; + } } - setPower(ind, val); - int retval = getPower(ind); - validate(&ret, mess, val, retval, "set power regulator", DEC); -} - -int getPower(enum DACINDEX ind, int* retval, char* mess) { - *retval = getPower(ind); - LOG(logDEBUG1, ("Power regulator(%d): %d\n", ind, retval)); -} - - - -void 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; - - 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; -} - -int getDAC(enum DACINDEX ind, int mV) { - if (!mV) { - LOG(logDEBUG1, ("Getting DAC %d : %d dac\n", ind, dacValues[ind])); - return dacValues[ind]; + // validate min value + if (val < 0) { + // dacs only: allow power down value (-100) + if ((ind < NDAC_ONLY && val != LTC2620_D_GetPowerDownValue()) || + // power regulators: allow no negative values + (ind >= NDAC_ONLY)) { + sprintf(mess, "Could not set DAC %d. Invalid value %d\n", ind, val); + LOG(logERROR, (mess)); + return FAIL; + } + } + // validate max value + if (val != LTC2620_D_GetPowerDownValue()) { + if (!mV) { + // dacs and power regs + if (val > LTC2620_D_GetMaxInput()) { + sprintf("Could not set DAC %d. Input %d exceeds max dac value %d\n", ind, val, LTC2620_D_GetMaxInput()); + LOG(logERROR, (mess)) + return FAIL; + } + // check vLimit - only dacs, convert to mV + if (vLimit > 0 && ind < NDAC_ONLY) { + int dacmV = 0; + if (LTC2620_D_DacToVoltage(val, &dacmV) == FAIL) { + sprintf(mess, "Could not set DAC %d. Could not convert input %d to mV\n", ind, val); + log(logERROR, (mess)); + return FAIL; + } + if (dacmV > vLimit) { + sprintf(mess, "Could not set DAC %d. Input %d (%d mV) exceeds vLimit value %d\n", ind, val, vLimit); + LOG(logERROR, (mess)); + return FAIL; + } + } + } + // only dacs in mV here + else { + if (val > DAC_MAX_MV) { + sprintf("Could not set DAC %d. Input %d mV exceeds max dac value %d mV\n", ind, val, DAC_MAX_MV); + LOG(logERROR, (mess)) + return FAIL; + } + if (vLimit > 0 && val > vLimit) { + sprintf("Could not set DAC %d. Input %d mV exceeds vLimit %d mV\n", ind, val, vLimit); + LOG(logERROR, (mess)) + return FAIL; + } + } } - int voltage = -1; - LTC2620_D_DacToVoltage(dacValues[ind], &voltage); - LOG(logDEBUG1, - ("Getting DAC %d : %d dac (%d mV)\n", ind, dacValues[ind], voltage)); - return voltage; -} - -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; return OK; } -int checkVLimitDacCompliant(int dac) { - if (vLimit > 0 && dac != -1 && dac != LTC2620_D_GetPowerDownValue()) { - int mv = 0; - // could not convert - if (LTC2620_D_DacToVoltage(dac, &mv) == FAIL) - return FAIL; - if (mv > vLimit) +int setDAC(enum DACINDEX ind, int val, int mV, char* mess) { + if (validateDAC(ind, val, mV, mess) == FAIL) + return FAIL; + + LOG(logINFO, ("Setting dac[%d]: %d %s \n", (int)ind, val, (mV ? "mV" : "dac units"))); + + // dacs only, mV, convert to dac value + int dacval = val; + if (mV && ind < NDAC_ONLY) { + if (LTC2620_D_VoltageToDac(val, &dacval) == FAIL) { + sprintf(mess, "Could not set DAC %d. Could not convert %d mV to dac units.\n", ind, val); + LOG(logERROR, (mess)); return FAIL; + } } + + if (LTC2620_D_SetDACValue((int)ind, dacval) == FAIL) { + sprintf(mess, "Could not set DAC %d. Failed to convert\n", ind); + LOG(logERROR, (mess)); + return FAIL; + } + + dacValues[ind] = dacval; + return OK; +} + +int getDAC(enum DACINDEX ind, int mV, int* retval, char* mess) { + // validate index + if (ind < 0 || ind > NDAC) { + sprintf(mess, "Could not get DAC %d. Invalid index.\n", ind); + LOG(logERROR, (mess)); + return FAIL; + } + // validate mV + if (mV && ind >= NDAC_ONLY) { + sprintf(mess, "Could not get DAC %d. Cannot convert to dac units for power regulator at this stage. Should have been earlier.\n"); + LOG(logERROR, (mess)); + return FAIL; + } + // get in dac units + if (!mV) { + LOG(logDEBUG1, ("Getting DAC %d : %d dac\n", ind, dacValues[ind])); + *retval = dacValues[ind]; + return OK; + } + // convert to mV + *retval = -1; + if (LTC2620_D_DacToVoltage(dacValues[ind], retval) == FAIL) { + sprintf(mess, "Could not get DAC %d. Could not convert %d dac units to mV\n", ind, dacValues[ind]); + LOG(logERROR, (mess)); + return FAIL; + } + LOG(logDEBUG1, + ("Getting DAC %d : %d dac (%d mV)\n", ind, dacValues[ind], *retval)); return OK; } @@ -1242,151 +1301,218 @@ int setVLimit(int val, char* mess) { vLimit = val; } -int getBitOffsetFromDACIndex(enum DACINDEX ind) { +int isPowerValid(enum PWRINDEX ind, int val, char* mess) { + char *powerNames[] = {PWR_NAMES}; + + int min = (ind == PWR_IO) ? VIO_MIN_MV : POWER_RGLTR_MIN; + int max = POWER_RGLTR_MAX; + // also checking vlimit if set + if (vLimit > 0 && vLimit < max) + max = vLimit; + + if (val != 0 && (val < min || val > max)) { + sprintf(mess, "Could not set %s. Invalid value. Must be between %d and %d mV\n", powerNames[ind], min, max); + LOG(logERROR, (mess)); + return FAIL; + } + return OK; +} + +int getPowerRailMask(enum PWRINDEX ind, uint32_t* mask, char* mess) { + mask = 0; + switch (ind) { + case PWR_IO: + *mask = POWER_VIO_MSK; + break; + case PWR_A: + *mask = POWER_VCC_A_MSK; + break; + case PWR_B: + *mask = POWER_VCC_B_MSK; + break; + case PWR_C: + *mask = POWER_VCC_C_MSK; + break; + case PWR_D: + *mask = POWER_VCC_D_MSK; + break; + default: + sprintf(mess, "Index %d has no power rail index\n", ind); + LOG(logERROR, (mess)); + return FAIL; + } + return OK; +} + + +int EnablePowerRail(enum PWRINDEX ind, char* mess) { + char *powerNames[] = {PWR_NAMES}; + uint32_t addr = CTRL_REG; + uint32_t mask = 0; + + if (getPowerRailMask(ind, &mask, mess) == FAIL) + return FAIL; + + LOG(logINFO, ("\tSwitching off power for %s\n", powerNames[ind])); + bus_w(addr, bus_r(addr) & ~(mask)); + return OK; +} + +int DisablePowerRail(enum PWRINDEX ind, char* mess) { + char *powerNames[] = {PWR_NAMES}; + uint32_t addr = CTRL_REG; + uint32_t mask = 0; + + if (getPowerRailMask(ind, &mask, mess) == FAIL) + return FAIL; + + LOG(logINFO, ("\tSwitching on power for %s\n", powerNames[ind])); + bus_w(addr, bus_r(addr) | mask); + return OK; +} + +int getPowerRail(enum PWRINDEX ind, int* retval, char* mess) { + char *powerNames[] = {PWR_NAMES}; + uint32_t addr = CTRL_REG; + uint32_t mask = 0; + + if (getPowerRailMask(ind, &mask, mess) == FAIL) + return FAIL; + + *retval = (bus_r(addr) & mask); + LOG(logDEBUG1, ("Power rail retval for %s: %s\n", powerNames[ind], ((*retval > 0) ? "Enabled" : "Disabled"))); + + return OK; +} + +// for power rail index and name debugging +int getPowerIndex(enum DACINDEX ind, enum PWRINDEX* pwrIndex, char* mess) { + pwrIndex = -1; switch (ind) { case D_PWR_IO: - return POWER_VIO_OFST; + *pwrIndex = PWR_IO; + break; case D_PWR_A: - return POWER_VCC_A_OFST; + *pwrIndex = PWR_A; + break; case D_PWR_B: - return POWER_VCC_B_OFST; + *pwrIndex = PWR_B; + break; case D_PWR_C: - return POWER_VCC_C_OFST; + *pwrIndex = PWR_C; + break; case D_PWR_D: - return POWER_VCC_D_OFST; + *pwrIndex = PWR_D; + break; default: - LOG(logERROR, - ("DAC index %d is not defined to get offset in ctrl register\n", - ind)); - return -1; + sprintf(mess, "Index %d has no power index\n", ind); + LOG(logERROR, (mess)); + return FAIL; } + return OK; } -int isPowerValid(enum DACINDEX ind, int val) { + + +int getPower(enum DACINDEX ind, int* retval, char* mess) { + enum PWRINDEX pwrIndex = 0; char *powerNames[] = {PWR_NAMES}; - int pwrIndex = (int)(ind - D_PWR_D); + *retval = -1; - int min = POWER_RGLTR_MIN; - if (!strcmp(powerNames[pwrIndex], "IO")) { - min = VIO_MIN_MV; - } - - // 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; - } + // validate index + if (getPowerIndex(ind, pwrIndex, mess) == FAIL) + return FAIL; // powered enable off - { - uint32_t addr = CTRL_REG; - uint32_t mask = (1 << bitOffset); - if (!(bus_r(addr) & mask)) - return 0; + int pwrRetval = 0; + if (getPowerRail(pwrIndex, &pwrRetval, mess) == FAIL) + return FAIL; + if (pwrRetval == 0) { + *retval = 0; + return OK; } - char *powerNames[] = {PWR_NAMES}; - int pwrIndex = (int)(ind - D_PWR_D); + // mV + if (convertPowerRegDACtoVoltage(pwrIndex, dacValues[ind], retval, mess) == FAIL) + return FAIL; - // not set 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(); - } - - // get dac in mV - int retval = -1; - ConvertToDifferentRange(LTC2620_D_GetMaxInput(), LTC2620_D_GetMinInput(), - POWER_RGLTR_MIN, POWER_RGLTR_MAX, dacValues[ind], - &retval); - - 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 convertPowerRegDACtoVoltage(enum PWRINDEX ind, int val, int* retval, 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; - } - - // Switch off power enable - LOG(logDEBUG1, ("Switching off power enable\n")); - bus_w(addr, bus_r(addr) & ~(mask)); - - // power down dac - LOG(logINFO, ("\tPowering down V%d\n", powerNames[pwrIndex])); - setDAC(ind, LTC2620_D_GetPowerDownValue(), 0); - - //(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()) { - - 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; - } - - // 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); - } + if (ConvertToDifferentRange(LTC2620_D_GetMaxInput(), LTC2620_D_GetMinInput(), POWER_RGLTR_MIN, POWER_RGLTR_MAX, val, retval) == FAIL) { + sprintf(mess, "Could not get %s. Could not convert %d dac to mV\n", powerNames[ind], val); + LOG(logERROR, (mess)); + return FAIL; } } +int convertPowerRegVoltagetoDAC(enum PWRINDEX ind, int val, int* retval, char* mess) { + char *powerNames[] = {PWR_NAMES}; + if (ConvertToDifferentRange(POWER_RGLTR_MIN, POWER_RGLTR_MAX, LTC2620_D_GetMaxInput(), LTC2620_D_GetMinInput(), val, retval) == FAIL) { + sprintf(mess, "Could not set %s. Invalid value %d mV to convert to dac units.\n", powerNames[ind], val); + LOG(logERROR, (mess)); + return FAIL; + } +} + +int initPower(enum DACINDEX ind, char* mess) { + if (ind == D_PWR_EMPTY) + return OK; + + enum PWRINDEX pwrIndex = 0; + if (getPowerIndex(ind, pwrIndex, initErrorMessage) == FAIL) + return FAIL; + + int dacval = 0; + int min = (ind == D_PWR_IO) ? VIO_MIN_MV : POWER_RGLTR_MIN; + if (convertPowerRegVoltagetoDAC(pwrIndex, min, &dacval, initErrorMessage) == FAIL) + return FAIL; + + if (setDAC(ind, dacval, 0, initErrorMessage) == FAIL) + return FAIL; + + return OK; +} + +int setPower(enum DACINDEX ind, int val, char* mess) { + enum PWRINDEX pwrIndex = 0; + char *powerNames[] = {PWR_NAMES}; + + // validate index + if (getPowerIndex(ind, pwrIndex, mess) == FAIL) + return FAIL; + + // validate values (invalidate power down) + if (!isPowerValid(pwrIndex, val, mess) == FAIL) + return FAIL; + + LOG(logINFOBLUE, ("Setting %s to %d mV\n", val)); + + if (DisablePowerRail(pwrIndex, mess) == FAIL) + return FAIL; + + // convert to dac units + int dacval = val; + if (val != LTC2620_GetPowerDownValue()) { + if (convertPowerRegVoltagetoDAC(pwrIndex, val, &dacval, mess) == FAIL) + return FAIL; + } + + LOG(logINFO, ("Setting %s (DAC %d): %d dac (%d mV)\n", powerNames[pwrIndex], dacval, val)); + if (setDAC(ind, dacval, 0, mess) == FAIL) + return FAIL; + + if (val != 0) { + if (EnablePowerRail(pwrIndex, mess) == FAIL) + return FAIL; + } + + return OK; +} + + int getADC(enum ADCINDEX ind, int *value) { *value = 0; #ifdef VIRTUAL diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.h b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.h index aad9fd43c..33bba8796 100644 --- a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.h +++ b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorFunctionList.h @@ -119,23 +119,31 @@ int64_t getMeasurementTime(); int setModule(sls_detector_module myMod, char *mess); // parameters - dac, adc, hv -void setDAC(enum DACINDEX ind, int val, int mV); -int getDAC(enum DACINDEX ind, int mV); -int getMaxDacSteps(); -int dacToVoltage(int dac); -int checkVLimitCompliant(int mV); -int checkVLimitDacCompliant(int dac); +int validateDAC(enum DACINDEX ind, int val, int mV, char* mess); +int setDAC(enum DACINDEX ind, int val, int mV, char* mess); +int getDAC(enum DACINDEX ind, int mV, int* retval, char* mess); int getVLimit(); int setVLimit(int val, char* mess); -int getBitOffsetFromDACIndex(enum DACINDEX ind); -int isPowerValid(enum DACINDEX ind, int val); + +int getPowerRailMask(enum PWRINDEX ind, uint32_t* mask, char* mess); +int EnablePowerRail(enum PWRINDEX ind, char* mess); +int DisablePowerRail(enum PWRINDEX ind, char* mess); +int getPowerRail(enum PWRINDEX ind, int* retval, char* mess); + +int isPowerValid(enum PWRINDEX ind, int val, char* mess); +int getPowerIndex(enum DACINDEX ind, enum PWRINDEX* pwrIndex, char* mess); + +int convertPowertoDACUnits(enum PWRINDEX ind, int val, int* retval, char* mess); +int initPower(enum DACINDEX ind, char* mess); int getPower(enum DACINDEX ind, int* retval, char* mess); int setPower(enum DACINDEX ind, int val, char* mess); + int getADC(enum ADCINDEX ind, int *value); int getSlowADC(int ichan, int *retval); int getTemperature(int *retval); int setHighVoltage(int val); + // parameters - timing, extsig void setTiming(enum timingMode arg); enum timingMode getTiming(); diff --git a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorServer_defs.h index 0ac8e1d5d..3fd920348 100644 --- a/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/xilinx_ctbDetectorServer/slsDetectorServer_defs.h @@ -119,7 +119,10 @@ enum DACINDEX { D_PWR_C }; -#define PWR_NAMES "D", "_unknown", "IO", "A", "B", "C" + +enum PWRINDEX { PWR_IO, PWR_A, PWR_B, PWR_C, PWR_D}; +#define PWR_NAMES "VIO", "VA", "VB", "VC", "VD" + /* Struct Definitions */ // For arm has to be multiple of 16