gotthard2: timingsource and currentsource features, (timing source external yet to be implemented in fpga to test (#80)

This commit is contained in:
Dhanya Thattil 2020-02-28 12:45:02 +01:00 committed by GitHub
parent 2e2e91b219
commit 11e7737a2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 334 additions and 3 deletions

View File

@ -104,6 +104,8 @@
#define CONTROL_PRPHRL_RST_MSK (0x00000001 << CONTROL_PRPHRL_RST_OFST)
#define CONTROL_CLR_ACQSTN_FIFO_OFST (15)
#define CONTROL_CLR_ACQSTN_FIFO_MSK (0x00000001 << CONTROL_CLR_ACQSTN_FIFO_OFST)
#define CONTROL_TIMING_SOURCE_EXT_OFST (17)
#define CONTROL_TIMING_SOURCE_EXT_MSK (0x00000001 << CONTROL_TIMING_SOURCE_EXT_OFST)
#define CONTROL_PWR_CHIP_OFST (31)
#define CONTROL_PWR_CHIP_MSK (0x00000001 << CONTROL_PWR_CHIP_OFST)
@ -128,6 +130,8 @@
#define ASIC_CONFIG_FIX_GAIN_1_VAL ((0x1 << ASIC_CONFIG_GAIN_OFST) & ASIC_CONFIG_GAIN_MSK)
#define ASIC_CONFIG_FIX_GAIN_2_VAL ((0x2 << ASIC_CONFIG_GAIN_OFST) & ASIC_CONFIG_GAIN_MSK)
#define ASIC_CONFIG_RESERVED_VAL ((0x3 << ASIC_CONFIG_GAIN_OFST) & ASIC_CONFIG_GAIN_MSK)
#define ASIC_CONFIG_CURRENT_SRC_EN_OFST (7)
#define ASIC_CONFIG_CURRENT_SRC_EN_MSK (0x00000001 << ASIC_CONFIG_CURRENT_SRC_EN_OFST)
#define ASIC_CONFIG_RST_DAC_OFST (15)
#define ASIC_CONFIG_RST_DAC_MSK (0x00000001 << ASIC_CONFIG_RST_DAC_OFST)
#define ASIC_CONFIG_DONE_OFST (31)

View File

@ -447,6 +447,8 @@ void setupDetector() {
setDelayAfterTrigger(DEFAULT_DELAY_AFTER_TRIGGER);
setBurstPeriod(DEFAULT_BURST_PERIOD);
setTiming(DEFAULT_TIMING_MODE);
setCurrentSource(DEFAULT_CURRENT_SOURCE);
setTimingSource(DEFAULT_TIMING_SOURCE);
}
int readConfigFile() {
@ -1961,6 +1963,44 @@ enum burstMode getBurstMode() {
return burstMode;
}
void setCurrentSource(int value) {
uint32_t addr = ASIC_CONFIG_REG;
if (value > 0) {
bus_w(addr, (bus_r(addr) | ASIC_CONFIG_CURRENT_SRC_EN_MSK));
} else if (value == 0) {
bus_w(addr, (bus_r(addr) &~ ASIC_CONFIG_CURRENT_SRC_EN_MSK));
}
}
int getCurrentSource() {
return ((bus_r(ASIC_CONFIG_REG) & ASIC_CONFIG_CURRENT_SRC_EN_MSK) >> ASIC_CONFIG_CURRENT_SRC_EN_OFST);
}
void setTimingSource(enum timingSourceType value) {
uint32_t addr = CONTROL_REG;
switch (value) {
case TIMING_INTERNAL:
FILE_LOG(logINFO, ("Setting timing source to internal\n"));
bus_w(addr, (bus_r(addr) &~ CONTROL_TIMING_SOURCE_EXT_MSK));
break;
case TIMING_EXTERNAL:
FILE_LOG(logINFO, ("Setting timing source to exernal\n"));
bus_w(addr, (bus_r(addr) | CONTROL_TIMING_SOURCE_EXT_MSK));
break;
default:
FILE_LOG(logERROR, ("Unknown timing source %d\n", value));
break;
}
}
enum timingSourceType getTimingSource() {
if (bus_r(CONTROL_REG) & CONTROL_TIMING_SOURCE_EXT_MSK) {
return TIMING_EXTERNAL;
}
return TIMING_INTERNAL;
}
/* aquisition */

View File

@ -41,6 +41,9 @@
#define DEFAULT_HIGH_VOLTAGE (0)
#define DEFAULT_TIMING_MODE (AUTO_TIMING)
#define DEFAULT_SETTINGS (DYNAMICGAIN)
#define DEFAULT_CURRENT_SOURCE (0)
#define DEFAULT_TIMING_SOURCE (TIMING_INTERNAL)
#define DEFAULT_READOUT_C0 (144444448) // rdo_clk, 144 MHz
#define DEFAULT_READOUT_C1 (144444448) // rdo_x2_clk, 144 MHz
#define DEFAULT_SYSTEM_C0 (144444448) // run_clk, 144 MHz

View File

@ -482,6 +482,10 @@ int configureADC();
int setBurstModeinFPGA(enum burstMode value);
int setBurstMode(enum burstMode burst);
enum burstMode getBurstMode();
void setCurrentSource(int value);
int getCurrentSource();
void setTimingSource(enum timingSourceType value);
enum timingSourceType getTimingSource();
#endif

View File

@ -212,3 +212,7 @@ int get_num_bursts(int);
int set_num_bursts(int);
int get_burst_period(int);
int set_burst_period(int);
int get_current_source(int);
int set_current_source(int);
int get_timing_source(int);
int set_timing_source(int);

View File

@ -319,6 +319,10 @@ const char* getFunctionName(enum detFuncs func) {
case F_SET_NUM_BURSTS: return "F_SET_NUM_BURSTS";
case F_GET_BURST_PERIOD: return "F_GET_BURST_PERIOD";
case F_SET_BURST_PERIOD: return "F_SET_BURST_PERIOD";
case F_GET_CURRENT_SOURCE: return "F_GET_CURRENT_SOURCE";
case F_SET_CURRENT_SOURCE: return "F_SET_CURRENT_SOURCE";
case F_GET_TIMING_SOURCE: return "F_GET_TIMING_SOURCE";
case F_SET_TIMING_SOURCE: return "F_SET_TIMING_SOURCE";
default: return "Unknown Function";
}
@ -507,6 +511,10 @@ void function_table() {
flist[F_SET_NUM_BURSTS] = &set_num_bursts;
flist[F_GET_BURST_PERIOD] = &get_burst_period;
flist[F_SET_BURST_PERIOD] = &set_burst_period;
flist[F_GET_CURRENT_SOURCE] = &get_current_source;
flist[F_SET_CURRENT_SOURCE] = &set_current_source;
flist[F_GET_TIMING_SOURCE] = &get_timing_source;
flist[F_SET_TIMING_SOURCE] = &set_timing_source;
// check
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
@ -6735,4 +6743,102 @@ int set_burst_period(int file_des) {
}
#endif
return Server_SendResult(file_des, INT64, UPDATE, NULL, 0);
}
int set_current_source(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int arg = 0;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
FILE_LOG(logINFO, ("Setting current source enable: %u\n", arg));
#ifndef GOTTHARD2D
functionNotImplemented();
#else
// only set
if (Server_VerifyLock() == OK) {
setCurrentSource(arg);
int retval = getCurrentSource();
FILE_LOG(logDEBUG1, ("current source enable retval: %u\n", retval));
validate(arg, retval, "current source enable", DEC);
}
#endif
return Server_SendResult(file_des, INT32, UPDATE, NULL, 0);
}
int get_current_source(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
int retval = -1;
FILE_LOG(logDEBUG1, ("Getting current source enable\n"));
#ifndef GOTTHARD2D
functionNotImplemented();
#else
// get only
retval = getCurrentSource();
FILE_LOG(logDEBUG1, ("current source enable retval: %u\n", retval));
#endif
return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval));
}
int set_timing_source(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
enum timingSourceType arg = TIMING_INTERNAL;
if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0)
return printSocketReadError();
FILE_LOG(logDEBUG1, ("Setting timing source: %d\n", arg));
#ifndef GOTTHARD2D
functionNotImplemented();
#else
// only set
if (Server_VerifyLock() == OK) {
switch (arg) {
case TIMING_INTERNAL:
case TIMING_EXTERNAL:
break;
default:
modeNotImplemented("timing source", (int)arg);
break;
}
if (ret == OK) {
setTimingSource(arg);
enum timingSourceType retval = getTimingSource();
FILE_LOG(logDEBUG, ("timing source retval: %d\n", retval));
if (retval != arg) {
ret = FAIL;
sprintf(mess, "Could not set timing source. Set %d, got %d\n", arg, retval);
FILE_LOG(logERROR, (mess));
}
}
}
#endif
return Server_SendResult(file_des, INT32, UPDATE, NULL, 0);
}
int get_timing_source(int file_des) {
ret = OK;
memset(mess, 0, sizeof(mess));
enum timingSourceType retval = TIMING_INTERNAL;
FILE_LOG(logDEBUG1, ("Getting timing source\n"));
#ifndef GOTTHARD2D
functionNotImplemented();
#else
// get only
retval = getTimingSource();
FILE_LOG(logDEBUG1, ("Get timing source retval:%d\n", retval));
#endif
return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval));
}

View File

@ -931,6 +931,18 @@ class Detector {
/** [Gotthard2] BURST_OFF, BURST_INTERNAL (default), BURST_EXTERNAL */
void setBurstMode(defs::burstMode value, Positions pos = {});
/** [Gotthard2] */
Result<bool> getCurrentSource(Positions pos = {}) const;
/** default disabled */
void setCurrentSource(bool value, Positions pos = {});
/** [Gotthard2] */
Result<defs::timingSourceType> getTimingSource(Positions pos = {}) const;
/** [Gotthard2] Options: TIMING_INTERNAL, TIMING_EXTERNAL */
void setTimingSource(defs::timingSourceType value, Positions pos = {});
/**************************************************
* *
* Mythen3 Specific *

View File

@ -790,6 +790,8 @@ class CmdProxy {
{"vetophoton", &CmdProxy::VetoPhoton},
{"vetoref", &CmdProxy::VetoReference},
{"burstmode", &CmdProxy::BurstMode},
{"currentsource", &CmdProxy::currentsource},
{"timingsource", &CmdProxy::timingsource},
/* Mythen3 Specific */
{"counters", &CmdProxy::Counters},
@ -1564,6 +1566,12 @@ class CmdProxy {
"[0, 1]\n\t[Gotthard] 1 adds channel intensity with precalculated values when taking an acquisition. Default is 0.");
/* Gotthard2 Specific */
INTEGER_COMMAND(currentsource, getCurrentSource, setCurrentSource, std::stoi,
"[0, 1]\n\t[Gotthard2] Enable or disable current source. Default is disabled.");
INTEGER_COMMAND(timingsource, getTimingSource, setTimingSource, sls::StringTo<slsDetectorDefs::timingSourceType>,
"[internal|external]\n\t[Gotthard2] Timing source. Internal is crystal and external is system timing. Default is internal.");
/* Mythen3 Specific */
/* CTB Specific */

View File

@ -1204,6 +1204,22 @@ void Detector::setBurstMode(defs::burstMode value, Positions pos) {
pimpl->Parallel(&slsDetector::setBurstMode, pos, value);
}
Result<bool> Detector::getCurrentSource(Positions pos) const {
return pimpl->Parallel(&slsDetector::getCurrentSource, pos);
}
void Detector::setCurrentSource(bool value, Positions pos) {
pimpl->Parallel(&slsDetector::setCurrentSource, pos, value);
}
Result<defs::timingSourceType> Detector::getTimingSource(Positions pos) const {
return pimpl->Parallel(&slsDetector::getTimingSource, pos);
}
void Detector::setTimingSource(defs::timingSourceType value, Positions pos) {
pimpl->Parallel(&slsDetector::setTimingSource, pos, value);
}
// Mythen3 Specific
Result<uint32_t> Detector::getCounterMask(Positions pos) const {

View File

@ -2546,6 +2546,32 @@ void slsDetector::setBurstMode(slsDetectorDefs::burstMode value) {
shm()->burstMode = value;
}
bool slsDetector::getCurrentSource() {
int retval = -1;
sendToDetector(F_GET_CURRENT_SOURCE, nullptr, retval);
FILE_LOG(logDEBUG1) << "Current source enable:" << retval;
return static_cast<bool>(retval);
}
void slsDetector::setCurrentSource(bool value) {
int arg = static_cast<int>(value);
FILE_LOG(logDEBUG1) << "Setting current source enable to " << arg;
sendToDetector(F_SET_CURRENT_SOURCE, arg, nullptr);
}
slsDetectorDefs::timingSourceType slsDetector::getTimingSource() {
int retval = -1;
sendToDetector(F_GET_TIMING_SOURCE, nullptr, retval);
FILE_LOG(logDEBUG1) << "Timing source:" << retval;
return static_cast<slsDetectorDefs::timingSourceType>(retval);
}
void slsDetector::setTimingSource(slsDetectorDefs::timingSourceType value) {
int arg = static_cast<int>(value);
FILE_LOG(logDEBUG1) << "Setting timing source to " << arg;
sendToDetector(F_SET_TIMING_SOURCE, arg, nullptr);
}
int slsDetector::setCounterBit(int cb) {
int retval = -1;
FILE_LOG(logDEBUG1) << "Sending counter bit " << cb;

View File

@ -1152,6 +1152,18 @@ class slsDetector : public virtual slsDetectorDefs {
/** [Gotthard2] BURST_OFF, BURST_INTERNAL (default), BURST_EXTERNAL */
void setBurstMode(burstMode value);
/** [Gotthard2] */
bool getCurrentSource();
/** default disabled */
void setCurrentSource(bool value);
/** [Gotthard2] */
slsDetectorDefs::timingSourceType getTimingSource();
/** [Gotthard2] Options: TIMING_INTERNAL, TIMING_EXTERNAL */
void setTimingSource(slsDetectorDefs::timingSourceType value);
/**
* Set/get counter bit in detector (Gotthard)

View File

@ -282,3 +282,62 @@ TEST_CASE("burstperiod", "[.cmd]") {
}
TEST_CASE("currentsource", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2) {
auto prev_val = det.getCurrentSource();
{
std::ostringstream oss;
proxy.Call("currentsource", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "currentsource 1\n");
}
{
std::ostringstream oss;
proxy.Call("currentsource", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "currentsource 0\n");
}
{
std::ostringstream oss;
proxy.Call("currentsource", {}, -1, GET, oss);
REQUIRE(oss.str() == "currentsource 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setCurrentSource(prev_val[i], {i});
}
} else {
REQUIRE_THROWS(proxy.Call("currentsource", {}, -1, GET));
}
}
TEST_CASE("timingsource", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2) {
auto prev_val = det.getTimingSource();
/* { until its activated in fpga
std::ostringstream oss;
proxy.Call("timingsource", {"external"}, -1, PUT, oss);
REQUIRE(oss.str() == "timingsource external\n");
}*/
{
std::ostringstream oss;
proxy.Call("timingsource", {"internal"}, -1, PUT, oss);
REQUIRE(oss.str() == "timingsource internal\n");
}
{
std::ostringstream oss;
proxy.Call("timingsource", {}, -1, GET, oss);
REQUIRE(oss.str() == "timingsource internal\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setTimingSource(prev_val[i], {i});
}
} else {
REQUIRE_THROWS(proxy.Call("timingsource", {}, -1, GET));
}
}

View File

@ -217,6 +217,18 @@ inline std::string ToString(const defs::burstMode s) {
}
}
inline std::string ToString(const defs::timingSourceType s) {
switch (s) {
case defs::TIMING_INTERNAL:
return std::string("internal");
case defs::TIMING_EXTERNAL:
return std::string("external");
default:
return std::string("Unknown");
}
}
// in case we already have a string
// causes a copy but might be needed in generic code
inline std::string ToString(const std::string& s) {
@ -574,6 +586,15 @@ inline defs::burstMode StringTo(const std::string& s) {
throw sls::RuntimeError("Unknown burst mode " + s);
}
template <>
inline defs::timingSourceType StringTo(const std::string& s) {
if (s == "internal")
return defs::TIMING_INTERNAL;
if (s == "external")
return defs::TIMING_EXTERNAL;
throw sls::RuntimeError("Unknown timing source type " + s);
}
/** For types with a .str() method use this for conversion */
template <typename T>

View File

@ -444,9 +444,17 @@ class slsDetectorDefs {
enum burstMode {
BURST_OFF,
BURST_INTERNAL,
BURST_EXTERNAL,
BURST_EXTERNAL
};
/**
* timing source for gotthard2
*/
enum timingSourceType {
TIMING_INTERNAL,
TIMING_EXTERNAL
};
#ifdef __cplusplus
protected:

View File

@ -192,6 +192,10 @@ enum detFuncs{
F_SET_NUM_BURSTS,
F_GET_BURST_PERIOD,
F_SET_BURST_PERIOD,
F_GET_CURRENT_SOURCE,
F_SET_CURRENT_SOURCE,
F_GET_TIMING_SOURCE,
F_SET_TIMING_SOURCE,
NUM_DET_FUNCTIONS,
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this (detector server should not compile anyway) */
@ -451,7 +455,11 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) {
case F_GET_NUM_BURSTS: return "F_GET_NUM_BURSTS";
case F_SET_NUM_BURSTS: return "F_SET_NUM_BURSTS";
case F_GET_BURST_PERIOD: return "F_GET_BURST_PERIOD";
case F_SET_BURST_PERIOD: return "F_SET_BURST_PERIOD";
case F_SET_BURST_PERIOD: return "F_SET_BURST_PERIOD";
case F_GET_CURRENT_SOURCE: return "F_GET_CURRENT_SOURCE";
case F_SET_CURRENT_SOURCE: return "F_SET_CURRENT_SOURCE";
case F_GET_TIMING_SOURCE: return "F_GET_TIMING_SOURCE";
case F_SET_TIMING_SOURCE: return "F_SET_TIMING_SOURCE";
case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";

View File

@ -1,7 +1,6 @@
/** API versions */
#define GITBRANCH "developer"
#define APIMOENCH 0x200131
#define APIGOTTHARD2 0x200226
#define APIMYTHEN3 0x200226
#define APIJUNGFRAU 0x200226
#define APIEIGER 0x200226
@ -10,3 +9,4 @@
#define APIRECEIVER 0x200227
#define APIGUI 0x200227
#define APICTB 0x200227
#define APIGOTTHARD2 0x200228