Compare commits

...

20 Commits

Author SHA1 Message Date
0a69516459 need ot fix ctb tests as well, a lot of refactoring
All checks were successful
Build on RHEL9 / build (push) Successful in 3m23s
Build on RHEL8 / build (push) Successful in 5m4s
2026-01-15 17:41:45 +01:00
0aab505645 xilinx: wip: dac to voltage needs to be separated and a default value needed or return a -1 for not defined
All checks were successful
Build on RHEL9 / build (push) Successful in 3m17s
Build on RHEL8 / build (push) Successful in 4m45s
2026-01-14 17:01:10 +01:00
ae793af7b9 refactor LTC2620 writedac
All checks were successful
Build on RHEL9 / build (push) Successful in 3m17s
Build on RHEL8 / build (push) Successful in 4m43s
2026-01-14 14:59:02 +01:00
c04e8e0beb binaries in
All checks were successful
Build on RHEL9 / build (push) Successful in 3m34s
Build on RHEL8 / build (push) Successful in 4m31s
2026-01-14 10:56:35 +01:00
3619577b69 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 2026-01-14 10:37:08 +01:00
c09f92b043 xilinx: setDAC and setPower returns, setPower cannot set < vmin or 0, setDAC ensures dac value for power regulators cannot be power down value, remove virtual isTransceiverAligned to always return 1 2026-01-13 14:16:14 +01:00
0ba1139741 remove hardcoded MH02 startup
All checks were successful
Build on RHEL9 / build (push) Successful in 3m45s
Build on RHEL8 / build (push) Successful in 4m51s
Build on local RHEL9 / build (push) Successful in 1m25s
Build on local RHEL8 / build (push) Successful in 3m32s
2026-01-13 11:05:37 +01:00
045d9440de Dev/include file (#1306)
All checks were successful
Build on local RHEL9 / build (push) Successful in 1m25s
Build on local RHEL8 / build (push) Successful in 3m32s
Build on RHEL9 / build (push) Successful in 4m17s
Build on RHEL8 / build (push) Successful in 4m35s
* create a include command calling the same function as parameters (cmd generation and autocompletion), testing parameters and include

* added include in command line and python and its supposed to do the same as parameters command. both are tested

* added colorama

* moved test_free and test_command python tests to tests/scripts folder from python/tests due to CI issues with dependencies

* generated commands

* formatting

---------

Co-authored-by: Erik Fröjdh <erik.frojdh@gmail.com>
2026-01-07 10:45:26 +01:00
874ff353e5 virtual servers compile fix for xilinxfmc (#1352)
All checks were successful
Build on local RHEL9 / build (push) Successful in 1m25s
Build on local RHEL8 / build (push) Successful in 3m31s
Build on RHEL8 / build (push) Successful in 4m36s
Build on RHEL9 / build (push) Successful in 4m36s
2026-01-06 14:38:11 +01:00
Martin Mueller
10879d32da Merge pull request #1351 from slsdetectorgroup/MH02_debug
XCTB updates
2026-01-06 11:42:29 +01:00
66f9664bc4 fprintf should return 2 including terminating character as well. formatting.
Some checks failed
Build on RHEL9 / build (push) Failing after 31s
Build on RHEL8 / build (push) Successful in 4m58s
2026-01-06 09:53:55 +01:00
c154164eff refactoring
Some checks failed
Build on RHEL9 / build (push) Failing after 30s
Build on RHEL8 / build (push) Successful in 4m43s
2026-01-05 17:51:54 +01:00
d95dff56e4 add back XCTB server binary 2026-01-05 17:03:50 +01:00
32c7afa134 Merge branch 'developer' into MH01_debug 2026-01-05 15:26:15 +01:00
df654ca23d Merge branch 'developer' into MH02_debug 2026-01-05 14:51:37 +01:00
d939dc7e4a update APIXILINXCTB 2026-01-05 14:30:30 +01:00
bcd22af9ba switch XCTB regDefs to cheby output 2026-01-05 13:53:30 +01:00
dece2e16b4 update registerDefs.h
All checks were successful
Build on RHEL9 / build (push) Successful in 3m9s
Build on RHEL8 / build (push) Successful in 4m35s
2026-01-05 09:31:32 +01:00
8063560e3a added FMC control
All checks were successful
Build on RHEL9 / build (push) Successful in 4m33s
Build on RHEL8 / build (push) Successful in 5m48s
2025-11-26 12:16:30 +01:00
178851fcf2 Merge branch 'developer' into MH02_debug
All checks were successful
Build on RHEL9 / build (push) Successful in 3m52s
Build on RHEL8 / build (push) Successful in 5m26s
2025-11-20 14:44:43 +01:00
37 changed files with 1734 additions and 939 deletions

View File

@@ -149,6 +149,33 @@ class Detector(CppDetectorApi):
value = ut.make_string_path(value)
self.loadParameters(value)
@property
def include(self):
"""Sets detector measurement parameters to those contained in fname.
Set up per measurement.
Note
-----
Equivalent to config, but does not free shared memory. Same as parameters command.
:getter: Not implemented
:setter: loads parameters file
Example
---------
>>> d.include = 'path/to/file.par'
"""
return NotImplementedError("include is set only")
@include.setter
def include(self, value):
if isinstance(value, str):
value = ut.make_string_path(value)
self.loadParameters(value)
@property
def hostname(self):
"""Frees shared memory and sets hostname (or IP address) of all modules concatenated by +

View File

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

View File

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

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

View File

@@ -0,0 +1,5 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
int XILINX_FMC_enable_all(char *error_message, int message_size);
int XILINX_FMC_disable_all(char *error_message, int message_size);

View File

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

View File

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

View File

@@ -0,0 +1,83 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "XILINX_FMC.h"
#include "arm64.h"
#include "clogger.h"
#include <math.h>
#include <stdbool.h>
#include <unistd.h>
// clang-format off
#define FMC_BASE_PATH "/root/fmc/"
#define FMC_VADJ_EN "FMC_VADJ_EN"
#define FMCP_VADJ_EN "FMCP_VADJ_EN"
#define FMCP_3V3_EN "FMCP_3V3_EN"
#define FMC_3V3_EN "FMC_3V3_EN"
#define FMC_12V_EN "FMC_12V_EN"
#define FMCP_12V_EN "FMCP_12V_EN"
static const char *fmc_files[] = {
FMC_VADJ_EN,
FMCP_VADJ_EN,
FMCP_3V3_EN,
FMC_3V3_EN,
FMC_12V_EN,
FMCP_12V_EN
};
#define FMC_NUM_FILES (sizeof(fmc_files) / sizeof(fmc_files[0]))
// clang-format on
int XILINX_FMC_enable_all(char *error_message, int message_size) {
LOG(logINFOBLUE, ("enable FMC power\n"));
#ifdef VIRTUAL
return 0;
#endif
char full_path[64];
for (size_t i = 0; i < FMC_NUM_FILES; ++i) {
const char *file = fmc_files[i];
snprintf(full_path, sizeof(full_path), "%s%s", FMC_BASE_PATH, file);
FILE *fp = fopen(full_path, "w");
if (fp == NULL) {
snprintf(error_message, message_size,
"XILINX_FMC: Couuld not enable.\n");
LOG(logERROR, (error_message));
return 1;
}
if (fprintf(fp, "1\n") != 2) {
snprintf(error_message, message_size,
"XILINX_FMC: Could not write enable.\n");
LOG(logERROR, (error_message));
return 1;
}
fclose(fp);
}
return 0;
}
int XILINX_FMC_disable_all(char *error_message, int message_size) {
LOG(logINFOBLUE, ("disable FMC power\n"));
#ifdef VIRTUAL
return 0;
#endif
char full_path[64];
for (size_t i = 0; i < FMC_NUM_FILES; ++i) {
const char *file = fmc_files[i];
snprintf(full_path, sizeof(full_path), "%s%s", FMC_BASE_PATH, file);
FILE *fp = fopen(full_path, "w");
if (fp == NULL) {
snprintf(error_message, message_size,
"XILINX_FMC: Could not disable\n");
LOG(logERROR, (error_message));
return 1;
}
if (fprintf(fp, "0\n") != 2) {
snprintf(error_message, message_size,
"XILINX_FMC: Could not write disable.\n");
LOG(logERROR, (error_message));
return 1;
}
fclose(fp);
}
return 0;
}

View File

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

View File

@@ -7,6 +7,7 @@ add_executable(xilinx_ctbDetectorServer_virtual
../slsDetectorServer/src/communication_funcs.c
../slsDetectorServer/src/arm64.c
../slsDetectorServer/src/XILINX_PLL.c
../slsDetectorServer/src/XILINX_FMC.c
../slsDetectorServer/src/common.c
../slsDetectorServer/src/sharedMemory.c
../slsDetectorServer/src/loadPattern.c

View File

@@ -23,7 +23,7 @@ DESTDIR ?= bin
INSTMODE = 0777
SRCS = slsDetectorFunctionList.c
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)arm64.c $(main_src)XILINX_PLL.c $(main_src)common.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c $(md5_dir)md5.c $(main_src)programViaArm.c $(main_src)LTC2620_Driver.c
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)arm64.c $(main_src)XILINX_PLL.c $(main_src)XILINX_FMC.c $(main_src)common.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c $(md5_dir)md5.c $(main_src)programViaArm.c $(main_src)LTC2620_Driver.c
OBJS = $(SRCS:.c=.o)

File diff suppressed because it is too large Load Diff

View File

@@ -1,24 +1 @@
# Prepare MH02 configuration
reg 0xC00C 0x00040041
reg 0xC010 0x01200004
# configure Matterhorn SPI
setbit 0xC014 0
# wait till config is done
pollbit 0xC014 3 0
# reset transceiver
reg 0xC120 0x0
reg 0xC120 0x1
reg 0xC120 0x0
# set MSB LSB inversions and polarity for transceiver
reg 0xC120 0x1e0
# Enable MH02 PLL clock
pattern enable_clock_pattern.pyat
# start the flow
setbit 0xB030 0
clearbit 0xB030 0
sleep 1
# nothing

View File

@@ -1,39 +1,2 @@
# turn off clock
clearbit 0xB018 15
setbit 0xB010 15
sleep 1
# reset Matterhorn periphery
setbit 0xC014 1
sleep 1
# turn on clock
clearbit 0xB010 15
sleep 1
# reset rx transceiver datapath
setbit 0xC120 4
sleep 1
# reset 8b10b counters
setbit 0xC120 9
setbit 0xC120 10
setbit 0xC120 11
setbit 0xC120 12
sleep 1
clearbit 0xC120 9
clearbit 0xC120 10
# reset buffer fifos
reg 0x9024 0xFFFFFFFF
reg 0x9028 0xFFFFFFFF
reg 0x902C 0xFFFFFFFF
reg 0x9024 0x0
reg 0x9028 0x0
reg 0x902C 0x0
setbit 0xA000 18
# load default pattern
pattern readout_pattern.pyat
# nothing

View File

@@ -9,8 +9,8 @@
#include "sls/versionAPI.h"
#include "LTC2620_Driver.h"
#include "XILINX_FMC.h"
#include "XILINX_PLL.h"
#include "loadPattern.h"
#ifdef VIRTUAL
#include "communication_funcs_UDP.h"
@@ -257,17 +257,17 @@ int testFixedFPGAPattern() {
LOG(logINFO, ("Testing FPGA Fixed Pattern:\n"));
#ifndef VIRTUAL
uint32_t val = bus_r(FIXEDPATTERNREG);
if (val == FIXEDPATTERNVAL) {
if (val == FIXEDPATTERNREG_PRESET) {
LOG(logINFO, ("\tFixed pattern: successful match (0x%08x)\n", val));
} else {
LOG(logERROR,
("Fixed pattern does not match! Read 0x%08x, expected 0x%08x\n",
val, FIXEDPATTERNVAL));
val, FIXEDPATTERNREG_PRESET));
return FAIL;
}
#endif
LOG(logINFO,
("\tSuccessfully read FPGA Fixed Pattern (0x%x)\n", FIXEDPATTERNVAL));
LOG(logINFO, ("\tSuccessfully read FPGA Fixed Pattern (0x%x)\n",
FIXEDPATTERNREG_PRESET));
return OK;
}
@@ -404,10 +404,31 @@ 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);
if (initError == FAIL) {
return;
}
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();
@@ -492,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) {
@@ -579,9 +595,10 @@ int powerChip(int on, char *mess) {
} else {
LOG(logINFOBLUE, ("Powering chip: off\n"));
bus_w(addr, bus_r(addr) & ~mask);
chipConfigured = 0;
if (FAIL == XILINX_FMC_disable_all(mess, MAX_STR_LENGTH)) {
return FAIL;
}
#ifdef VIRTUAL
setTransceiverAlignment(0);
#endif
@@ -1143,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;
@@ -1172,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;
@@ -1205,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) {
@@ -1381,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) {

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

View File

@@ -80,7 +80,7 @@ _sd() {
local IS_PATH=0
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern define_bit define_reg definelist_bit definelist_reg delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern define_bit define_reg definelist_bit definelist_reg delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest include initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
__acquire() {
FCN_RETURN=""
return 0
@@ -1262,6 +1262,21 @@ fi
fi
return 0
}
__include() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="0 1"
fi
fi
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
IS_PATH=1
fi
fi
return 0
}
__initialchecks() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then

View File

@@ -4,7 +4,7 @@
_sd() {
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern define_bit define_reg definelist_bit definelist_reg delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
local SLS_COMMANDS=" acquire activate adcclk adcenable adcenable10g adcindex adcinvert adclist adcname adcphase adcpipeline adcreg adcvpp apulse asamples autocompdisable badchannels blockingtrigger burstmode burstperiod bursts burstsl bustest cdsgain chipversion clearbit clearbusy clientversion clkdiv clkfreq clkphase collectionmode column compdisabletime confadc config configtransceiver counters currentsource dac dacindex daclist dacname dacvalues datastream dbitclk dbitphase dbitpipeline defaultdac defaultpattern define_bit define_reg definelist_bit definelist_reg delay delayl detectorserverversion detsize diodelay dpulse dr drlist dsamples execcommand exptime exptime1 exptime2 exptime3 extrastoragecells extsampling extsamplingsrc extsig fformat filtercells filterresistor findex firmwaretest firmwareversion fliprows flowcontrol10g fmaster fname foverwrite fpath framecounter frames framesl frametime free fwrite gaincaps gainmode gappixels gatedelay gatedelay1 gatedelay2 gatedelay3 gates getbit hardwareversion highvoltage hostname im_a im_b im_c im_d im_io imagetest include initialchecks inj_ch interpolation interruptsubframe kernelversion lastclient led lock master maxadcphaseshift maxclkphaseshift maxdbitphaseshift measuredperiod measuredsubperiod moduleid nextframenumber nmod numinterfaces overflow packageversion parallel parameters partialreset patfname patioctrl patlimits patloop patloop0 patloop1 patloop2 patmask patnloop patnloop0 patnloop1 patnloop2 patsetbit pattern patternstart patwait patwait0 patwait1 patwait2 patwaittime patwaittime0 patwaittime1 patwaittime2 patword pedestalmode period periodl polarity port powerchip powerindex powerlist powername powervalues programfpga pulse pulsechip pulsenmove pumpprobe quad ratecorr readnrows readout readoutspeed readoutspeedlist rebootcontroller reg resetdacs resetfpga romode row runclk runtime rx_arping rx_clearroi rx_dbitlist rx_dbitoffset rx_dbitreorder rx_discardpolicy rx_fifodepth rx_frameindex rx_framescaught rx_framesperfile rx_hostname rx_jsonaddheader rx_jsonpara rx_lastclient rx_lock rx_missingpackets rx_padding rx_printconfig rx_realudpsocksize rx_roi rx_silent rx_start rx_status rx_stop rx_tcpport rx_threads rx_udpsocksize rx_version rx_zmqfreq rx_zmqhwm rx_zmqip rx_zmqport rx_zmqstartfnum rx_zmqstream samples savepattern scan scanerrmsg selinterface serialnumber setbit settings settingslist settingspath signalindex signallist signalname sleep slowadc slowadcindex slowadclist slowadcname slowadcvalues start status stop stopport storagecell_delay storagecell_start subdeadtime subexptime sync syncclk temp_10ge temp_adc temp_control temp_dcdc temp_event temp_fpga temp_fpgaext temp_fpgafl temp_fpgafr temp_slowadc temp_sodl temp_sodr temp_threshold templist tempvalues tengiga threshold thresholdnotb timing timing_info_decoder timinglist timingsource top transceiverenable trigger triggers triggersl trimbits trimen trimval tsamples txdelay txdelay_frame txdelay_left txdelay_right type udp_cleardst udp_dstip udp_dstip2 udp_dstlist udp_dstmac udp_dstmac2 udp_dstport udp_dstport2 udp_firstdst udp_numdst udp_reconfigure udp_srcip udp_srcip2 udp_srcmac udp_srcmac2 udp_validate update updatedetectorserver updatekernel updatemode user v_a v_b v_c v_chip v_d v_io v_limit vchip_comp_adc vchip_comp_fe vchip_cs vchip_opa_1st vchip_opa_fd vchip_ref_comp_fe versions veto vetoalg vetofile vetophoton vetoref vetostream virtual vm_a vm_b vm_c vm_d vm_io zmqhwm zmqip zmqport "
__acquire() {
FCN_RETURN=""
return 0
@@ -1186,6 +1186,21 @@ fi
fi
return 0
}
__include() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 1 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN="0 1"
fi
fi
if [[ ${IS_GET} -eq 0 ]]; then
if [[ "${cword}" == "2" ]]; then
FCN_RETURN=""
IS_PATH=1
fi
fi
return 0
}
__initialchecks() {
FCN_RETURN=""
if [[ ${IS_GET} -eq 0 ]]; then

View File

@@ -1846,6 +1846,13 @@ parameters:
PUT:
function: loadParameters
include:
inherit_actions: EXECUTE_SET_COMMAND_NOID_1ARG
help: "\n\tSets detector measurement parameters to those contained in fname. Set up per measurement. Same as parameters command."
actions:
PUT:
function: loadParameters
savepattern:
inherit_actions: EXECUTE_SET_COMMAND_NOID_1ARG
help: "\n\t[Ctb][Mythen3][Xilinx Ctb] Saves pattern to file (ascii). \n\t[Ctb] Also executes pattern."

View File

@@ -5092,6 +5092,32 @@ imagetest:
\ pixel intensity incremented by 1. If 1, all pixels almost saturated."
infer_action: true
template: true
include:
actions:
PUT:
args:
- arg_types:
- special::path
argc: 1
cast_input:
- false
check_det_id: true
convert_det_id: true
function: loadParameters
input:
- args[0]
input_types:
- std::string
output:
- args.front()
require_det_id: false
store_result_in_t: false
command_name: include
function_alias: include
help: "\n\tSets detector measurement parameters to those contained in fname. Set\
\ up per measurement. Same as parameters command."
infer_action: true
template: true
initialchecks:
actions:
GET:

View File

@@ -6227,6 +6227,48 @@ std::string Caller::imagetest(int action) {
return os.str();
}
std::string Caller::include(int action) {
std::ostringstream os;
// print help
if (action == slsDetectorDefs::HELP_ACTION) {
os << R"V0G0N(
Sets detector measurement parameters to those contained in fname. Set up per measurement. Same as parameters command. )V0G0N"
<< std::endl;
return os.str();
}
// check if action and arguments are valid
if (action == slsDetectorDefs::PUT_ACTION) {
if (1 && args.size() != 1) {
throw RuntimeError("Wrong number of arguments for action PUT");
}
if (args.size() == 1) {
}
}
else {
throw RuntimeError(
"INTERNAL ERROR: Invalid action: supported actions are ['PUT']");
}
// generate code for each action
if (action == slsDetectorDefs::PUT_ACTION) {
if (args.size() == 1) {
if (det_id != -1) {
throw RuntimeError("Cannot execute include at module level");
}
det->loadParameters(args[0]);
os << args.front() << '\n';
}
}
return os.str();
}
std::string Caller::initialchecks(int action) {
std::ostringstream os;

View File

@@ -165,6 +165,7 @@ class Caller {
std::string im_d(int action);
std::string im_io(int action);
std::string imagetest(int action);
std::string include(int action);
std::string initialchecks(int action);
std::string inj_ch(int action);
std::string interpolation(int action);
@@ -531,6 +532,7 @@ class Caller {
{"im_d", &Caller::im_d},
{"im_io", &Caller::im_io},
{"imagetest", &Caller::imagetest},
{"include", &Caller::include},
{"initialchecks", &Caller::initialchecks},
{"inj_ch", &Caller::inj_ch},
{"interpolation", &Caller::interpolation},

View File

@@ -1686,6 +1686,18 @@ int InferAction::imagetest() {
}
}
int InferAction::include() {
if (args.size() == 1) {
return slsDetectorDefs::PUT_ACTION;
}
else {
throw RuntimeError("Could not infer action: Wrong number of arguments");
}
}
int InferAction::initialchecks() {
if (args.size() == 0) {

View File

@@ -120,6 +120,7 @@ class InferAction {
int im_d();
int im_io();
int imagetest();
int include();
int initialchecks();
int inj_ch();
int interpolation();
@@ -456,6 +457,7 @@ class InferAction {
{"im_d", &InferAction::im_d},
{"im_io", &InferAction::im_io},
{"imagetest", &InferAction::imagetest},
{"include", &InferAction::include},
{"initialchecks", &InferAction::initialchecks},
{"inj_ch", &InferAction::inj_ch},
{"interpolation", &InferAction::interpolation},

View File

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

View File

@@ -46,32 +46,46 @@ TEST_CASE("config", "[.cmdcall]") {
// free: not testing
TEST_CASE("parameters", "[.cmdcall]") {
void test_include_file(const std::string &cmd) {
Detector det;
Caller caller(&det);
// put only
REQUIRE_THROWS(caller.call("parameters", {}, -1, GET));
/*
auto prev_val = det.getNumberOfFrames().tsquash("Number of frames has to
be same to test");
{
system("echo 'frames 2' > /tmp/tempsetup.det ");
std::ostringstream oss;
caller.call("parameters", {"/tmp/tempsetup.det"}, -1, PUT, oss);
REQUIRE(oss.str() == "parameters /tmp/tempsetup.det\n");
REQUIRE(det.getNumberOfFrames().tsquash("failed") == 2);
}
{
system("echo '0:frames 1' > /tmp/tempsetup.det ");
std::ostringstream oss;
caller.call("parameters", {"/tmp/tempsetup.det"}, -1, PUT, oss);
REQUIRE(oss.str() == "parameters /tmp/tempsetup.det\n");
REQUIRE(det.getNumberOfFrames({0}).tsquash("failed") == 1);
}
det.setNumberOfFrames(prev_val);
*/
REQUIRE_THROWS(caller.call(cmd, {}, -1, GET));
auto prev_frames = det.getNumberOfFrames().tsquash(
"Number of frames has to be same to test");
auto prev_fwrite =
det.getFileWrite().tsquash("File write enable has to be same to test");
{
system("echo -e 'frames 2\nfwrite 1' > /tmp/tempsetup.det ");
std::ostringstream oss;
caller.call(cmd, {"/tmp/tempsetup.det"}, -1, PUT, oss);
REQUIRE(oss.str() == cmd + " /tmp/tempsetup.det\n");
REQUIRE(det.getNumberOfFrames().tsquash(
"frames inconsistent and failed") == 2);
REQUIRE(det.getFileWrite().tsquash("fwrite inconsistent and failed") ==
1);
}
{
system("echo -e 'frames 3\nfwrite 0' > /tmp/tempsetup.det ");
std::ostringstream oss;
caller.call(cmd, {"/tmp/tempsetup.det"}, -1, PUT, oss);
REQUIRE(oss.str() == cmd + " /tmp/tempsetup.det\n");
REQUIRE(det.getNumberOfFrames().tsquash(
"frames inconsistent and failed") == 3);
REQUIRE(det.getFileWrite().tsquash("fwrite inconsistent and failed") ==
0);
}
det.setNumberOfFrames(prev_frames);
det.setFileWrite(prev_fwrite);
}
TEST_CASE("parameters", "[.cmdcall]") { test_include_file("parameters"); }
TEST_CASE("include", "[.cmdcall]") { test_include_file("include"); }
TEST_CASE("hostname", "[.cmdcall]") {
Detector det;
Caller caller(&det);

View File

@@ -804,7 +804,7 @@ typedef struct {
}
sls_detector_module &operator=(const sls_detector_module &other) {
if(this == &other)
if (this == &other)
return *this;
delete[] dacs;
delete[] chanregs;

View File

@@ -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 0x251015"
#define APIXILINXCTB "0.0.0 0x260115"
#define APIJUNGFRAU "0.0.0 0x250909"
#define APIMYTHEN3 "0.0.0 0x250922"
#define APIMYTHEN3 "0.0.0 0x260114"

View File

@@ -62,3 +62,5 @@ configure_file(scripts/test_frame_synchronizer.py ${CMAKE_BINARY_DIR}/bin/test_f
configure_file(scripts/utils_for_test.py ${CMAKE_BINARY_DIR}/bin/utils_for_test.py COPYONLY)
configure_file(scripts/test_roi.py ${CMAKE_BINARY_DIR}/bin/test_roi.py COPYONLY)
configure_file(scripts/test_free.py ${CMAKE_BINARY_DIR}/bin/test_free.py COPYONLY)
configure_file(scripts/test_commands.py ${CMAKE_BINARY_DIR}/bin/test_commands.py COPYONLY)

View File

@@ -0,0 +1,100 @@
# SPDX-License-Identifier: LGPL-3.0-or-other
# Copyright (C) 2021 Contributors to the SLS Detector Package
'''
This file is used to start up simulators and test for freeing shm and accessing it from python.
Run this using: pytest -s test_free.py
'''
from time import time
import pytest, sys, time
from slsdet import Detector, Ctb, freeSharedMemory
from slsdet.defines import DEFAULT_TCP_RX_PORTNO
from utils_for_test import (
Log,
LogLevel,
cleanup,
startDetectorVirtualServer,
startProcessInBackground,
loadConfig,
loadBasicSettings
)
def startReceiver(num_mods, fp):
if num_mods == 1:
cmd = ['slsReceiver']
else:
cmd = ['slsMultiReceiver', str(DEFAULT_TCP_RX_PORTNO), str(num_mods)]
# in 10.0.0
#cmd = ['slsMultiReceiver', '-p', str(DEFAULT_TCP_RX_PORTNO), '-n', str(num_mods)]
startProcessInBackground(cmd, fp)
time.sleep(1)
'''
scope = module =>Once per test file/module
to share expensive setup like startDetectorVirtualServer
'''
@pytest.fixture(scope="module")
def det_config():
return {
"name": "ctb",
"num_mods": 1
}
# autouse is false to pass explictly
@pytest.fixture(scope="module", autouse=False)
def setup_simulator(det_config):
"""Fixture to start the detector server once and clean up at the end."""
fp = sys.stdout
cleanup(fp)
# server
startDetectorVirtualServer(det_config["name"], det_config["num_mods"], fp)
# receiver
startReceiver(det_config["num_mods"], fp)
# config and basic settings
d = loadConfig(name=det_config["name"], rx_hostname="localhost", settingsdir="", fp=fp, num_mods=det_config["num_mods"])
loadBasicSettings(name=det_config["name"], d=d, fp=fp)
yield d # tests run here
cleanup(fp)
def test_parameters_file(setup_simulator):
d = setup_simulator
Log(LogLevel.INFOBLUE, f'\nRunning test_parameters_file')
assert isinstance(d, Detector)
with open("/tmp/params.det", "w") as f:
f.write("frames 2\n")
f.write("fwrite 1\n")
# this should not throw
d.parameters = "/tmp/params.det"
assert d.frames == 2
assert d.fwrite == 1
Log(LogLevel.INFOGREEN, f"✅ Test passed. Command: parameters")
def test_include_file(setup_simulator):
d = setup_simulator
Log(LogLevel.INFOBLUE, f'\test_include_file test_parameters_file')
assert isinstance(d, Detector)
with open("/tmp/params.det", "w") as f:
f.write("frames 3\n")
f.write("fwrite 0\n")
# this should not throw
d.include = "/tmp/params.det"
assert d.frames == 3
assert d.fwrite == 0
Log(LogLevel.INFOGREEN, f"✅ Test passed. Command: include")

View File

@@ -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']: