wip
Build on RHEL9 docker image / build (push) Failing after 28s
Build on RHEL8 docker image / build (push) Failing after 34s

This commit is contained in:
2026-03-13 11:35:21 +01:00
parent 951304c39c
commit afb808aef8
7 changed files with 192 additions and 85 deletions
@@ -1431,25 +1431,34 @@ int setDAC(enum DACINDEX ind, int val, bool mV, char *mess) {
return FAIL;
int dacval = val;
char dacName[20] = {0};
snprintf(dacName, sizeof(dacName), "dac %d", ind);
if (mV) {
if (validateDACValue(ind, val, mess) == FAIL)
return FAIL;
// power dacs (power should be disabled)
if (ind >= NDAC_ONLY && ind != D_PWR_CHIP) {
if (verifyPowerRailDisabled(ind, mess) == FAIL)
// vchip dac (dacname only())
if (ind == D_PWR_CHIP) {
snprintf(dacName, sizeof(dacName), "v_chip");
}
// power dacs (dacname and power should be disabled)
else if (ind >= NDAC_ONLY) {
{
enum PWRINDEX pwrIndex = PWR_IO;
if (getPowerIndexFromDACIndex(ind, &pwrIndex, mess) == FAIL)
return FAIL;
char *powerNames[] = {PWR_NAMES};
snprintf(dacName, sizeof(dacName), "%s", powerNames[pwrIndex]);
}
if (verifyPowerRailDisabled(ind, dacName, mess) == FAIL)
return FAIL;
}
if (convertVoltageToDACValue(ind, val, &dacval, mess) == FAIL)
return FAIL;
}
{
char dacName[20] = {0};
snprintf(dacName, sizeof(dacName), "dac %d", ind);
if (LTC2620_SetDacValue((int)ind, dacval, dacName, mess) == FAIL)
return FAIL;
}
if (LTC2620_SetDacValue((int)ind, dacval, dacName, mess) == FAIL)
return FAIL;
dacValues[ind] = dacval;
return OK;
}
@@ -1485,7 +1494,7 @@ int getVchip(int *retval, char *mess) {
}
int setVchip(int val, char *mess) {
LOG(logINFOBLUE, ("Setting Vchip to %d mV\n", val));
LOG(logDEBUG, ("\tSetting Vchip to %d mV\n", val));
if (setDAC(D_PWR_CHIP, val, true, mess) == FAIL)
return FAIL;
@@ -1618,22 +1627,32 @@ int setPowerRailEnabled(enum DACINDEX indices[], int count, bool enable,
// get power indices for log messages and mask
uint32_t mask = 0;
enum PWRINDEX pwrIndices[count];
char *powerNames[] = {PWR_NAMES};
for (int i = 0; i != count; ++i) {
if (getPowerIndexFromDACIndex(indices[i], &pwrIndices[i], mess) == FAIL)
if (getPowerIndexFromDACIndex(indices[i], &pwrIndices[i], mess) ==
FAIL) {
sprintf(mess,
"Cannot set power rail for %s. Use powerlist to see whats "
"available.\n",
powerNames[pwrIndices[i]]);
return FAIL;
}
LOG(logDEBUG1,
("Setting power rail for %s\n", powerNames[pwrIndices[i]]));
if (getPowerRailMask(pwrIndices[i], &mask, mess) == FAIL)
return FAIL;
}
// log message
{
char *powerNames[] = {PWR_NAMES};
char message[256] = {0};
sprintf(message, "Switching %s power for ", enable ? "on" : "off");
for (int i = 0; i != count; ++i) {
strcat(message, powerNames[pwrIndices[i]]);
strcat(message, " ");
}
strcat(message, "\n");
LOG(logINFO, ("%s", message));
LOG(logINFOBLUE, ("%s", message));
}
// set vchip accordingly
@@ -1655,31 +1674,33 @@ int setPowerRailEnabled(enum DACINDEX indices[], int count, bool enable,
int isPowerRailEnabled(enum DACINDEX ind, bool *retval, char *mess) {
enum PWRINDEX pwrIndex = PWR_IO;
if (getPowerIndexFromDACIndex(ind, &pwrIndex, mess) == FAIL)
if (getPowerIndexFromDACIndex(ind, &pwrIndex, mess) == FAIL) {
char *powerNames[] = {PWR_NAMES};
sprintf(mess,
"Cannot set power rail for %s. Use powerlist to see whats "
"available.\n",
powerNames[pwrIndex]);
return FAIL;
}
uint32_t mask = 0;
if (getPowerRailMask(pwrIndex, &mask, mess) == FAIL)
return FAIL;
*retval = (bus_r(POWER_REG) & mask) != 0;
LOG(logDEBUG1, ("get power %d:%d\n", pwrIndex, *retval));
return OK;
}
int verifyPowerRailDisabled(enum DACINDEX ind, char *mess) {
int verifyPowerRailDisabled(enum DACINDEX ind, char *dacName, char *mess) {
bool isEnabled = false;
if (isPowerRailEnabled(ind, &isEnabled, mess) == FAIL)
return FAIL;
if (isEnabled) {
enum PWRINDEX pwrIndex = PWR_IO;
if (getPowerIndexFromDACIndex(ind, &pwrIndex, mess) == FAIL)
return FAIL;
char *powerNames[] = {PWR_NAMES};
sprintf(mess,
"Could not set dac for %s. Please disable the power rail "
"before setting the dac value.\n",
powerNames[pwrIndex]);
dacName);
LOG(logERROR, (mess));
return FAIL;
}
@@ -1689,11 +1710,11 @@ int verifyPowerRailDisabled(enum DACINDEX ind, char *mess) {
void powerChip(bool enable) {
uint32_t addr = POWER_REG;
if (enable) {
LOG(logINFO, ("Powering on all voltage regulators\n"));
LOG(logINFOBLUE, ("Powering on all voltage regulators\n"));
bus_w(addr, bus_r(addr) | POWER_ENBL_VLTG_RGLTR_MSK);
return;
} else {
LOG(logINFO, ("Powering off all voltage regulators\n"));
LOG(logINFOBLUE, ("Powering off all voltage regulators\n"));
bus_w(addr, bus_r(addr) & (~POWER_ENBL_VLTG_RGLTR_MSK));
}
}
@@ -154,7 +154,7 @@ int getPowerRailMask(enum PWRINDEX ind, uint32_t *mask, char *mess);
int setPowerRailEnabled(enum DACINDEX indices[], int count, bool enable,
char *mess);
int isPowerRailEnabled(enum DACINDEX ind, bool *retval, char *mess);
int verifyPowerRailDisabled(enum DACINDEX ind, char *mess);
int verifyPowerRailDisabled(enum DACINDEX ind, char *dacName, char *mess);
void powerChip(bool enable);
int getPowerChip();
@@ -250,7 +250,7 @@ int LTC2620_SetDacValue(int dacnum, int val, char *dacname, char *mess) {
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tSetting DAC %s [%d]: %d dac\n", dacname, dacnum, val));
LOG(logINFOBLUE, ("\tSetting DAC %s [%d]: %d dac\n", dacname, dacnum, val));
#ifndef VIRTUAL
LTC2620_SetDAC(dacnum, val);
#endif
@@ -5,6 +5,7 @@
#include "sls/Detector.h"
#include <iostream>
#include <optional>
#include <string>
#include <vector>
namespace sls {
@@ -92,6 +93,8 @@ class Caller {
// applicable
RegisterAddress getRegisterAddress(const std::string &saddr) const;
BitAddress getBitAddress() const;
defs::dacIndex parsePowerIndex(int argIndex);
std::optional<defs::dacIndex> parseIfPowerIndex(int argIndex);
defs::dacIndex parseDacIndex(int argIndex, bool isCtb);
bool parseMV(int argIndex);
+3
View File
@@ -5,6 +5,7 @@
#include "sls/Detector.h"
#include <iostream>
#include <optional>
#include <string>
#include <vector>
namespace sls {
@@ -416,6 +417,8 @@ class Caller {
// applicable
RegisterAddress getRegisterAddress(const std::string &saddr) const;
BitAddress getBitAddress() const;
defs::dacIndex parsePowerIndex(int argIndex);
std::optional<defs::dacIndex> parseIfPowerIndex(int argIndex);
defs::dacIndex parseDacIndex(int argIndex, bool isCtb);
bool parseMV(int argIndex);
+47 -12
View File
@@ -4,8 +4,10 @@
#include "sls/file_utils.h"
#include "sls/logger.h"
#include "sls/string_utils.h"
#include <iostream>
#include <thread>
namespace sls {
// some helper functions to print
@@ -1852,6 +1854,37 @@ std::string Caller::dac(int action) {
return os.str();
}
defs::dacIndex Caller::parsePowerIndex(int argIndex) {
auto res = parseIfPowerIndex(argIndex);
if (!res.has_value()) {
throw RuntimeError("Invalid power name. Power name can be v_a, v_b, "
"v_c, v_d, v_io, v_chip or any names set using "
"powername command.");
}
return res.value();
}
std::optional<defs::dacIndex> Caller::parseIfPowerIndex(int argIndex) {
if (argIndex >= (int)args.size()) {
throw RuntimeError("Invalid arguments. Power name is required.");
}
auto arg = args[argIndex];
// power default names
if (is_int(arg) || arg == "v_a" || arg == "v_b" || arg == "v_c" ||
arg == "v_d" || arg == "v_io" || arg == "v_chip") {
return std::make_optional(StringTo<defs::dacIndex>(arg));
}
// power name
auto names = det->getPowerNames();
auto it = std::find(names.begin(), names.end(), arg);
if (it != names.end()) {
return std::make_optional(det->getPowerIndex(arg));
}
return std::nullopt;
}
defs::dacIndex Caller::parseDacIndex(int argIndex, bool isCtb) {
if (argIndex >= (int)args.size()) {
throw RuntimeError("Invalid arguments. DAC index is required.");
@@ -1859,12 +1892,12 @@ defs::dacIndex Caller::parseDacIndex(int argIndex, bool isCtb) {
auto arg = args[argIndex];
if (isCtb) {
// dac index or power dacs
if (is_int(arg) || arg == "v_a" || arg == "v_b" || arg == "v_c" ||
arg == "v_d" || arg == "v_io" || arg == "v_chip") {
return StringTo<defs::dacIndex>(arg);
// power dacs
auto res = parseIfPowerIndex(argIndex);
if (res.has_value()) {
return res.value();
}
// dac name for ctb gui
// dac name
return det->getDacIndex(arg);
}
@@ -1936,8 +1969,8 @@ std::string Caller::power(int action) {
if (action == defs::HELP_ACTION) {
os << "[list of power names] [on|off]\n\t[Ctb][Xilinx Ctb] Enable or "
"disable power rails. Power name can be v_a, v_b, v_c, v_d or "
"v_io. If none provided, all of them are set to on or off. One "
"can retrieve only one at a time."
"v_io or any names set using powername. One can retrieve only "
"one at a time."
<< '\n';
return os.str();
}
@@ -1953,11 +1986,13 @@ std::string Caller::power(int action) {
if (args.size() != 1) {
WrongNumberOfParameters(1);
}
auto t = det->isPowerEnabled(StringTo<defs::dacIndex>(args[0]),
std::vector<int>{det_id})
.tsquash("Inconsistent across modules");
auto t =
det->isPowerEnabled(parsePowerIndex(0), std::vector<int>{det_id})
.tsquash("Inconsistent across modules");
os << args[0] << ' ' << ToString(t, defs::OnOff) << '\n';
} else if (action == defs::PUT_ACTION) {
}
else if (action == defs::PUT_ACTION) {
if (args.size() < 1 || args.size() > 6) {
WrongNumberOfParameters(1);
}
@@ -1969,7 +2004,7 @@ std::string Caller::power(int action) {
bool enable = StringTo(lastArg, defs::OnOff);
std::vector<defs::dacIndex> powerIndices;
for (size_t i = 0; i < args.size() - 1; ++i) {
powerIndices.push_back(StringTo<defs::dacIndex>(args[i]));
powerIndices.push_back(parsePowerIndex(i));
}
det->setPowerEnabled(powerIndices, enable, std::vector<int>{det_id});
@@ -573,15 +573,17 @@ TEST_CASE("dac", "[.detectorintegration][dacs]") {
REQUIRE_THROWS(caller.call("dac", {"5", "2049", "mV"}, -1, PUT));
for (int idac = 0; idac < 18; ++idac) {
SECTION("dac " + std::to_string(idac)) {
test_dac_caller(static_cast<defs::dacIndex>(idac), "dac", 0);
test_dac_caller(static_cast<defs::dacIndex>(idac), "dac", 1200);
test_dac_caller(static_cast<defs::dacIndex>(idac), "dac", 1200,
true);
test_dac_caller(static_cast<defs::dacIndex>(idac), "dac", -100);
// dac name
det.setDacName(static_cast<defs::dacIndex>(idac),
"dacname" + std::to_string(idac));
test_dac_caller(defs::DAC_0, "dacname" + std::to_string(idac),
-100);
}
@@ -660,6 +662,21 @@ TEST_CASE("dac", "[.detectorintegration][dacs]") {
REQUIRE(oss2.str() ==
"dac " + names[iPower] + " 1200 mV\n");
}
{
// power name
det.setPowerName(indices[iPower],
"pwrname_" + names[iPower]);
std::ostringstream oss1, oss2;
caller.call("dac",
{"pwrname_" + names[iPower], "1200", "mV"}, -1,
PUT, oss1);
REQUIRE(oss1.str() ==
"dac pwrname_" + names[iPower] + " 1200 mV\n");
caller.call("dac", {"pwrname_" + names[iPower], "mV"}, -1,
GET, oss2);
REQUIRE(oss2.str() ==
"dac pwrname_" + names[iPower] + " 1200 mV\n");
}
// throw if trying to set dac when power is on
{
det.setPowerEnabled(std::vector{indices[iPower]}, true);
@@ -1188,55 +1205,83 @@ TEST_CASE("power", "[.detectorintegration]") {
defs::V_POWER_C, defs::V_POWER_D,
defs::V_POWER_IO};
std::vector<bool> prev_val(cmds.size());
for (size_t iPower = 0; iPower < cmds.size(); ++iPower) {
auto prev_val = det.isPowerEnabled(indices[iPower]);
prev_val[iPower] = det.isPowerEnabled(indices[iPower])
.tsquash("Inconsistent power enabled state");
det.setPowerEnabled(std::vector{indices[iPower]}, false);
}
REQUIRE_THROWS(caller.call("power", {"vrandom"}, -1, GET));
REQUIRE_THROWS(caller.call("power", {"v_chip"}, -1, GET));
REQUIRE_THROWS(caller.call("power", {"on", "v_a"}, -1, PUT));
{
std::ostringstream oss;
caller.call("power", {"v_a", "on"}, -1, PUT, oss);
REQUIRE(oss.str() == "power [v_a] on\n");
}
{
std::ostringstream oss;
caller.call("power", {"v_a"}, -1, GET, oss);
REQUIRE(oss.str() == "power v_a on\n");
}
{
std::ostringstream oss;
caller.call("power", {"v_a", "v_c", "on"}, -1, PUT, oss);
REQUIRE(oss.str() == "power [v_a, v_c] on\n");
}
{
std::ostringstream oss1, oss2, oss3;
caller.call("power", {"v_a", "v_b", "off"}, -1, PUT);
caller.call("power", {"v_a"}, -1, GET, oss1);
caller.call("power", {"v_b"}, -1, GET, oss2);
caller.call("power", {"v_c"}, -1, GET, oss3);
REQUIRE(oss1.str() == "power v_a off\n");
REQUIRE(oss2.str() == "power v_b off\n");
REQUIRE(oss3.str() == "power v_c on\n");
}
{ // power chip
caller.call("powerchip", {"1"}, -1, PUT);
std::ostringstream oss1, oss2, oss3, oss4, oss5;
caller.call("power", {"v_a"}, -1, GET, oss1);
caller.call("power", {"v_b"}, -1, GET, oss2);
caller.call("power", {"v_c"}, -1, GET, oss3);
caller.call("power", {"v_d"}, -1, GET, oss4);
caller.call("power", {"v_io"}, -1, GET, oss5);
REQUIRE(oss1.str() == "power v_a on\n");
REQUIRE(oss2.str() == "power v_b on\n");
REQUIRE(oss3.str() == "power v_c on\n");
REQUIRE(oss4.str() == "power v_d on\n");
REQUIRE(oss5.str() == "power v_io on\n");
}
for (int imod = 0; imod != det.size(); ++imod) {
det.setPowerEnabled(std::vector{indices[iPower]},
prev_val[imod], {imod});
}
REQUIRE_THROWS(caller.call("power", {"vrandom"}, -1, GET));
REQUIRE_THROWS(caller.call("power", {"v_chip"}, -1, GET));
REQUIRE_THROWS(caller.call("power", {"on", "v_a"}, -1, PUT));
{
std::ostringstream oss;
caller.call("power", {"v_a", "on"}, -1, PUT, oss);
REQUIRE(oss.str() == "power [v_a] on\n");
}
{
std::ostringstream oss;
caller.call("power", {"v_a"}, -1, GET, oss);
REQUIRE(oss.str() == "power v_a on\n");
}
{
std::ostringstream oss;
caller.call("power", {"v_a", "v_c", "on"}, -1, PUT, oss);
REQUIRE(oss.str() == "power [v_a, v_c] on\n");
}
{
std::ostringstream oss1, oss2, oss3;
caller.call("power", {"v_a", "v_b", "off"}, -1, PUT);
caller.call("power", {"v_a"}, -1, GET, oss1);
caller.call("power", {"v_b"}, -1, GET, oss2);
caller.call("power", {"v_c"}, -1, GET, oss3);
REQUIRE(oss1.str() == "power v_a off\n");
REQUIRE(oss2.str() == "power v_b off\n");
REQUIRE(oss3.str() == "power v_c on\n");
}
{
// power name
std::ostringstream oss1;
det.setPowerName(defs::V_POWER_B, "pwrname_v_b");
det.setPowerName(defs::V_POWER_C, "pwrname_v_c");
det.setPowerName(defs::V_POWER_D, "pwrname_v_d");
caller.call("power", {"pwrname_v_c", "pwrname_v_d", "on"}, -1, PUT,
oss1);
std::ostringstream oss[8];
caller.call("power", {"v_a"}, -1, GET, oss[0]);
caller.call("power", {"pwrname_v_b"}, -1, GET, oss[1]);
caller.call("power", {"v_b"}, -1, GET, oss[2]);
caller.call("power", {"pwrname_v_c"}, -1, GET, oss[3]);
caller.call("power", {"v_c"}, -1, GET, oss[4]);
caller.call("power", {"pwrname_v_d"}, -1, GET, oss[5]);
caller.call("power", {"v_d"}, -1, GET, oss[6]);
caller.call("power", {"v_io"}, -1, GET, oss[7]);
REQUIRE(oss[0].str() == "power v_a off\n");
REQUIRE(oss[1].str() == "power pwrname_v_b off\n");
REQUIRE(oss[2].str() == "power v_b off\n");
REQUIRE(oss[3].str() == "power pwrname_v_c on\n");
REQUIRE(oss[4].str() == "power v_c on\n");
REQUIRE(oss[5].str() == "power pwrname_v_d on\n");
REQUIRE(oss[6].str() == "power v_d on\n");
REQUIRE(oss[7].str() == "power v_io off\n");
}
{ // power chip
caller.call("powerchip", {"1"}, -1, PUT);
std::ostringstream oss1, oss2, oss3, oss4, oss5;
caller.call("power", {"v_a"}, -1, GET, oss1);
caller.call("power", {"v_b"}, -1, GET, oss2);
caller.call("power", {"v_c"}, -1, GET, oss3);
caller.call("power", {"v_d"}, -1, GET, oss4);
caller.call("power", {"v_io"}, -1, GET, oss5);
REQUIRE(oss1.str() == "power v_a on\n");
REQUIRE(oss2.str() == "power v_b on\n");
REQUIRE(oss3.str() == "power v_c on\n");
REQUIRE(oss4.str() == "power v_d on\n");
REQUIRE(oss5.str() == "power v_io on\n");
}
for (size_t iPower = 0; iPower < cmds.size(); ++iPower) {
det.setPowerEnabled(std::vector{indices[iPower]}, prev_val[iPower]);
}
} else {
REQUIRE_THROWS(caller.call("power", {"v_a"}, -1, GET));