fixed warnings, LTC2620 driver: removed power down file name as it is only for xilinx and must be combined to create it, refactored its setDAC to be maintainable, xilinx:setDAC andsetPower returns ret and calls LTC2620 directly (setDAC in xilinx is only for dac and not power regualtors anymore), validate vlimit again before calling LTC2620 setdac, fixed transceiveralignment with xilinx ctb, changed file names to not include %d because its only allowed in macros and not variables

This commit is contained in:
2026-01-14 10:37:08 +01:00
parent c09f92b043
commit 3619577b69
9 changed files with 177 additions and 155 deletions

View File

@@ -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);

View File

@@ -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();

View File

@@ -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,12 @@ 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
* Set value for dac only
* @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);

View File

@@ -3,7 +3,13 @@
#include "LTC2620_Driver.h"
#include "clogger.h"
#include "common.h"
// to include power down file name suffix
#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,114 @@ 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 value
if ((dacvalue < 0 && dacvalue != LTC2620_D_PWR_DOWN_VAL) ||
(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")));
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
// 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));
}
// set in file
#ifndef VIRTUAL
#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));
// 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);
}

View File

@@ -1405,11 +1405,13 @@ int validateAndSetDac(enum dacIndex ind, int val, int mV) {
setDAC(serverDacIndex, val, mV, 0);
#elif defined(XILINX_CHIPTESTBOARDD)
{
ret = setDAC(serverDacIndex, val, mV);
if (ret == FAIL) {
sprintf(mess, "Setting dac %d to value %d failed.\n",
serverDacIndex, val);
LOG(logERROR, (mess));
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));
}
}
}
#else

View File

@@ -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);
@@ -418,7 +418,7 @@ void setupDetector() {
}
LOG(logINFOBLUE, ("Defaulting all power regulators to 0 mV.\n"));
for (int idac = NDAC_ONLY; idac < NDAC; ++idac) {
setDAC(idac, 0, 0);
setPower(idac, 0);
}
resetFlow();
@@ -503,11 +503,9 @@ 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
@@ -515,14 +513,14 @@ void setTransceiverAlignment(int align) {
int isTransceiverAligned() {
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) {
@@ -1153,40 +1151,43 @@ int64_t getMeasurementTime() {
/* parameters - dac, adc, hv */
int setDAC(enum DACINDEX ind, int val, int mV) {
// Cannot use power down value for power regulators
if (val == LTC2620_D_GetPowerDownValue()) {
switch (ind) {
case D_PWR_D:
case D_PWR_EMPTY:
case D_PWR_IO:
case D_PWR_A:
case D_PWR_B:
case D_PWR_C:
LOG(logERROR, ("Cannot power down Power regulators.\n"));
return FAIL;
default:
break;
}
}
char dacName[MAX_STR_LENGTH] = {0};
memset(dacName, 0, MAX_STR_LENGTH);
sprintf(dacName, "dac%d", (int)ind);
LOG(logDEBUG1, ("Setting dac[%d - %s]: %d %s \n", (int)ind, dacName, val,
(mV ? "mV" : "dac units")));
if (val < 0 && val != LTC2620_D_GetPowerDownValue()) {
LOG(logERROR,
("Invalid value %d for dac[%d - %s]\n", val, (int)ind, dacName));
// 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;
// ensure vlimit compliance
{
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
int dacval = -1;
if (LTC2620_D_SetDACValue((int)ind, val, mV, dacName, &dacval) == FAIL)
return FAIL;
dacValues[ind] = dacval;
return OK;
}
@@ -1266,8 +1267,16 @@ int isPowerValid(enum DACINDEX ind, int val) {
min = VIO_MIN_MV;
}
// check vlimit (already checked at funcs.c)
if (checkVLimitCompliant(val) == FAIL) {
LOG(logERROR,
("Invalid value of %d mV for Power V%s. Exceeds vLimit of %d mV\n",
val, powerNames[pwrIndex], vLimit));
return 0;
}
// not power_rgltr_max because it is allowed only upto vchip max - 200
if (val != 0 && (val < min || val > POWER_RGLTR_MAX)) {
if ((val != 0 && 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",
@@ -1319,6 +1328,9 @@ int getPower(enum DACINDEX ind) {
}
int setPower(enum DACINDEX ind, int val) {
if (!isPowerValid(ind, val)) {
return FAIL;
}
// validate index and get bit offset in ctrl register
int bitOffset = getBitOffsetFromDACIndex(ind);
@@ -1332,22 +1344,17 @@ int setPower(enum DACINDEX ind, int val) {
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)) {
return FAIL;
}
// Switch off power enable
LOG(logDEBUG1, ("\tSwitching off power enable\n"));
bus_w(addr, bus_r(addr) & ~(mask));
// power down dac (Cannot use power down value for power regulators)
if (setDAC(ind, 0, 0) == FAIL) {
// set dac value to 0
if (LTC2620_D_WriteDACValue((int)ind, 0, powerNames[pwrIndex]) == FAIL)
return FAIL;
}
dacValues[ind] = 0;
// convert voltage to dac
if (val != 0) {
if (val > 0) {
// convert voltage to dac
int dacval = -1;
if (ConvertToDifferentRange(
POWER_RGLTR_MIN, POWER_RGLTR_MAX, LTC2620_D_GetMaxInput(),
@@ -1360,14 +1367,15 @@ int setPower(enum DACINDEX ind, int val) {
return FAIL;
}
// set dac value
LOG(logINFO, ("\tSetting DAC V%s: %d mV (%d dac)\n",
powerNames[pwrIndex], val, dacval));
if (setDAC(ind, dacval, 0) == FAIL) {
LOG(logERROR,
("Could not set dac for Power V%s\n", powerNames[pwrIndex]));
if (LTC2620_D_WriteDACValue((int)ind, dacval, powerNames[pwrIndex]) ==
FAIL)
return FAIL;
}
dacValues[ind] = dacval;
// Switch on power enable
LOG(logDEBUG1, ("\tSwitching on power enable for Power V%s\n",
powerNames[pwrIndex]));
bus_w(addr, bus_r(addr) | mask);
@@ -1407,7 +1415,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) {

View File

@@ -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"

View File

@@ -7,6 +7,6 @@
#define APIGOTTHARD2 "0.0.0 0x250909"
#define APIMOENCH "0.0.0 0x250909"
#define APIEIGER "0.0.0 0x250909"
#define APIXILINXCTB "0.0.0 0x260113"
#define APIXILINXCTB "0.0.0 0x260114"
#define APIJUNGFRAU "0.0.0 0x250909"
#define APIMYTHEN3 "0.0.0 0x250922"