Merge branch 'jungfrau1.1' into j6mode

This commit is contained in:
maliakal_d 2021-08-02 08:55:46 +02:00
commit 526aa3273e
10 changed files with 172 additions and 76 deletions

View File

@ -18,7 +18,8 @@ Checks: '*,
-google-readability-todo, -google-readability-todo,
-google-readability-braces-around-statements, -google-readability-braces-around-statements,
-modernize-use-trailing-return-type, -modernize-use-trailing-return-type,
-readability-isolate-declaration' -readability-isolate-declaration,
-llvmlibc-*'
HeaderFilterRegex: \.h HeaderFilterRegex: \.h
AnalyzeTemporaryDtors: false AnalyzeTemporaryDtors: false

View File

@ -2040,7 +2040,7 @@ class Detector(CppDetectorApi):
[Jungfrau] Number of additional storage cells. [Jungfrau] Number of additional storage cells.
Note Note
---- ----
For advanced users only. \n Only for chip v1.0. For advanced users only. \n
Options: 0 - 15. Default is 0. Options: 0 - 15. Default is 0.
The #images = #frames x #triggers x (#storagecells + 1) The #images = #frames x #triggers x (#storagecells + 1)
""" """
@ -2059,7 +2059,7 @@ class Detector(CppDetectorApi):
Note Note
---- ----
For advanced users only. For advanced users only.
Options 0-15. Default is 15. \n Options 0-max. max is 15 (default) for chipv1.0 and 3 (default) for chipv1.1. \n
""" """
return self.getStorageCellStart() return self.getStorageCellStart()
@ -2073,7 +2073,7 @@ class Detector(CppDetectorApi):
[Jungfrau] Additional time delay between 2 consecutive exposures in burst mode, accepts either a value in seconds or datetime.timedelta [Jungfrau] Additional time delay between 2 consecutive exposures in burst mode, accepts either a value in seconds or datetime.timedelta
Note Note
----- -----
For advanced users only \n Only applicable for chipv1.0. For advanced users only \n
Value: 0-1638375 ns (resolution of 25ns) \n Value: 0-1638375 ns (resolution of 25ns) \n
:getter: always returns in seconds. To get in datetime.delta, use getStorageCellDelay :getter: always returns in seconds. To get in datetime.delta, use getStorageCellDelay

View File

@ -354,9 +354,28 @@ void init_det(py::module &m) {
py::arg(), py::arg() = Positions{}) py::arg(), py::arg() = Positions{})
.def("getDacList", (std::vector<defs::dacIndex>(Detector::*)() const) & .def("getDacList", (std::vector<defs::dacIndex>(Detector::*)() const) &
Detector::getDacList) Detector::getDacList)
.def("setDefaultDacs", .def("getDefaultDac",
(void (Detector::*)(sls::Positions)) & Detector::setDefaultDacs, (Result<int>(Detector::*)(defs::dacIndex, sls::Positions)) &
py::arg() = Positions{}) Detector::getDefaultDac,
py::arg(), py::arg() = Positions{})
.def("setDefaultDac",
(void (Detector::*)(defs::dacIndex, int, sls::Positions)) &
Detector::setDefaultDac,
py::arg(), py::arg(), py::arg() = Positions{})
.def("getDefaultDac",
(Result<int>(Detector::*)(defs::dacIndex, defs::detectorSettings,
sls::Positions)) &
Detector::getDefaultDac,
py::arg(), py::arg(), py::arg() = Positions{})
.def("setDefaultDac",
(void (Detector::*)(defs::dacIndex, int, defs::detectorSettings,
sls::Positions)) &
Detector::setDefaultDac,
py::arg(), py::arg(), py::arg(), py::arg() = Positions{})
.def("resetToDefaultDacs",
(void (Detector::*)(const bool, sls::Positions)) &
Detector::resetToDefaultDacs,
py::arg(), py::arg() = Positions{})
.def("getDAC", .def("getDAC",
(Result<int>(Detector::*)(defs::dacIndex, bool, sls::Positions) (Result<int>(Detector::*)(defs::dacIndex, bool, sls::Positions)
const) & const) &
@ -923,6 +942,10 @@ void init_det(py::module &m) {
sls::Positions)) & sls::Positions)) &
Detector::setDataStream, Detector::setDataStream,
py::arg(), py::arg(), py::arg() = Positions{}) py::arg(), py::arg(), py::arg() = Positions{})
.def("getChipVersion",
(Result<double>(Detector::*)(sls::Positions) const) &
Detector::getChipVersion,
py::arg() = Positions{})
.def("getThresholdTemperature", .def("getThresholdTemperature",
(Result<int>(Detector::*)(sls::Positions) const) & (Result<int>(Detector::*)(sls::Positions) const) &
Detector::getThresholdTemperature, Detector::getThresholdTemperature,
@ -947,10 +970,6 @@ void init_det(py::module &m) {
(void (Detector::*)(sls::Positions)) & (void (Detector::*)(sls::Positions)) &
Detector::resetTemperatureEvent, Detector::resetTemperatureEvent,
py::arg() = Positions{}) py::arg() = Positions{})
.def("getChipVersion",
(Result<double>(Detector::*)(sls::Positions) const) &
Detector::getChipVersion,
py::arg() = Positions{})
.def("getAutoCompDisable", .def("getAutoCompDisable",
(Result<bool>(Detector::*)(sls::Positions) const) & (Result<bool>(Detector::*)(sls::Positions) const) &
Detector::getAutoCompDisable, Detector::getAutoCompDisable,

View File

@ -457,9 +457,14 @@ void setupDetector() {
setExpTime(DEFAULT_EXPTIME); setExpTime(DEFAULT_EXPTIME);
setPeriod(DEFAULT_PERIOD); setPeriod(DEFAULT_PERIOD);
setDelayAfterTrigger(DEFAULT_DELAY); setDelayAfterTrigger(DEFAULT_DELAY);
setNumAdditionalStorageCells(DEFAULT_NUM_STRG_CLLS); if (getChipVersion() == 11) {
setStorageCellDelay(DEFAULT_STRG_CLL_DLY); selectStoragecellStart(DEFAULT_STRG_CLL_STRT_CHIP11);
selectStoragecellStart(DEFAULT_STRG_CLL_STRT); } else {
setNumAdditionalStorageCells(DEFAULT_NUM_STRG_CLLS);
selectStoragecellStart(DEFAULT_STRG_CLL_STRT);
// not applicable for chipv1.1
setStorageCellDelay(DEFAULT_STRG_CLL_DLY);
}
/*setClockDivider(RUN_CLK, HALF_SPEED); depends if all the previous stuff /*setClockDivider(RUN_CLK, HALF_SPEED); depends if all the previous stuff
* works*/ * works*/
setTiming(DEFAULT_TIMING_MODE); setTiming(DEFAULT_TIMING_MODE);
@ -773,14 +778,42 @@ uint32_t getADCInvertRegister() {
/* parameters - timer */ /* parameters - timer */
int selectStoragecellStart(int pos) { int selectStoragecellStart(int pos) {
int value = pos;
uint32_t addr = DAQ_REG;
uint32_t mask = DAQ_STRG_CELL_SLCT_MSK;
int offset = DAQ_STRG_CELL_SLCT_OFST;
if (getChipVersion() == 11) {
// set the bit
value = 1 << pos;
addr = CONFIG_V11_REG;
mask = CONFIG_V11_STRG_CLL_MSK;
offset = CONFIG_V11_STRG_CLL_OFST;
}
if (pos >= 0) { if (pos >= 0) {
LOG(logINFO, ("Setting storage cell start: %d\n", pos)); LOG(logINFO, ("Setting storage cell start: %d\n", pos));
bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_STRG_CELL_SLCT_MSK); bus_w(addr, bus_r(addr) & ~mask);
bus_w(DAQ_REG, bus_r(DAQ_REG) | ((pos << DAQ_STRG_CELL_SLCT_OFST) & bus_w(addr, bus_r(addr) | ((value << offset) & mask));
DAQ_STRG_CELL_SLCT_MSK)); }
int retval = ((bus_r(addr) & mask) >> offset);
if (getChipVersion() == 11) {
// get which bit
int max = getMaxStoragecellStart();
for (int i = 0; i != max + 1; ++i) {
if (retval & (1 << i)) {
return i;
}
}
}
// chip v1.0
return retval;
}
int getMaxStoragecellStart() {
if (getChipVersion() == 11) {
return MAX_STORAGE_CELL_CHIP11_VAL;
} else {
return MAX_STORAGE_CELL_VAL;
} }
return ((bus_r(DAQ_REG) & DAQ_STRG_CELL_SLCT_MSK) >>
DAQ_STRG_CELL_SLCT_OFST);
} }
int setNextFrameNumber(uint64_t value) { int setNextFrameNumber(uint64_t value) {

View File

@ -102,6 +102,7 @@ enum CLKINDEX { RUN_CLK, ADC_CLK, DBIT_CLK, NUM_CLOCKS };
#define DEFAULT_TMP_THRSHLD (65 * 1000) // milli degree Celsius #define DEFAULT_TMP_THRSHLD (65 * 1000) // milli degree Celsius
#define DEFAULT_NUM_STRG_CLLS (0) #define DEFAULT_NUM_STRG_CLLS (0)
#define DEFAULT_STRG_CLL_STRT (0xf) #define DEFAULT_STRG_CLL_STRT (0xf)
#define DEFAULT_STRG_CLL_STRT_CHIP11 (0x3)
#define DEFAULT_STRG_CLL_DLY (0) #define DEFAULT_STRG_CLL_DLY (0)
#define HIGHVOLTAGE_MIN (60) #define HIGHVOLTAGE_MIN (60)
@ -113,6 +114,7 @@ enum CLKINDEX { RUN_CLK, ADC_CLK, DBIT_CLK, NUM_CLOCKS };
#define MAX_TIMESLOT_VAL (0x1F) #define MAX_TIMESLOT_VAL (0x1F)
#define MAX_THRESHOLD_TEMP_VAL (127999) // millidegrees #define MAX_THRESHOLD_TEMP_VAL (127999) // millidegrees
#define MAX_STORAGE_CELL_VAL (15) // 0xF #define MAX_STORAGE_CELL_VAL (15) // 0xF
#define MAX_STORAGE_CELL_CHIP11_VAL (3)
#define MAX_STORAGE_CELL_DLY_NS_VAL (ASIC_CTRL_EXPSRE_TMR_MAX_VAL) #define MAX_STORAGE_CELL_DLY_NS_VAL (ASIC_CTRL_EXPSRE_TMR_MAX_VAL)
#define ACQ_TIME_MIN_CLOCK (2) #define ACQ_TIME_MIN_CLOCK (2)

View File

@ -202,6 +202,7 @@ int getReadoutMode();
// parameters - timer // parameters - timer
#ifdef JUNGFRAUD #ifdef JUNGFRAUD
int selectStoragecellStart(int pos); int selectStoragecellStart(int pos);
int getMaxStoragecellStart();
#endif #endif
#if defined(JUNGFRAUD) || defined(EIGERD) #if defined(JUNGFRAUD) || defined(EIGERD)
int setNextFrameNumber(uint64_t value); int setNextFrameNumber(uint64_t value);

View File

@ -2036,10 +2036,14 @@ int set_num_additional_storage_cells(int file_des) {
#else #else
// only set // only set
if (Server_VerifyLock() == OK) { if (Server_VerifyLock() == OK) {
if (arg > MAX_STORAGE_CELL_VAL) { if (getChipVersion() == 11) {
ret = FAIL;
sprintf(mess, "Cannot set addl. number of storage cells for chip v1.1\n");
LOG(logERROR, (mess));
} else if (arg > getMaxStoragecellStart()) {
ret = FAIL; ret = FAIL;
sprintf(mess, "Max Storage cell number should not exceed %d\n", sprintf(mess, "Max Storage cell number should not exceed %d\n",
MAX_STORAGE_CELL_VAL); getMaxStoragecellStart());
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} else { } else {
setNumAdditionalStorageCells(arg); setNumAdditionalStorageCells(arg);
@ -2483,9 +2487,15 @@ int get_storage_cell_delay(int file_des) {
functionNotImplemented(); functionNotImplemented();
#else #else
// get only // get only
retval = getStorageCellDelay(); if (getChipVersion() == 11) {
LOG(logDEBUG1, ret = FAIL;
strcpy(mess, "Storage cell delay is not applicable for chipv 1.1\n");
LOG(logERROR, (mess));
} else {
retval = getStorageCellDelay();
LOG(logDEBUG1,
("retval storage cell delay %lld ns\n", (long long int)retval)); ("retval storage cell delay %lld ns\n", (long long int)retval));
}
#endif #endif
return Server_SendResult(file_des, INT64, &retval, sizeof(retval)); return Server_SendResult(file_des, INT64, &retval, sizeof(retval));
} }
@ -2505,7 +2515,11 @@ int set_storage_cell_delay(int file_des) {
#else #else
// only set // only set
if (Server_VerifyLock() == OK) { if (Server_VerifyLock() == OK) {
if (arg > MAX_STORAGE_CELL_DLY_NS_VAL) { if (getChipVersion() == 11) {
ret = FAIL;
strcpy(mess, "Storage cell delay is not applicable for chipv 1.1\n");
LOG(logERROR, (mess));
} else if (arg > MAX_STORAGE_CELL_DLY_NS_VAL) {
ret = FAIL; ret = FAIL;
sprintf(mess, sprintf(mess,
"Max Storage cell delay value should not exceed %lld ns\n", "Max Storage cell delay value should not exceed %lld ns\n",
@ -4007,9 +4021,9 @@ int storage_cell_start(int file_des) {
#else #else
// set & get // set & get
if ((arg == GET_FLAG) || (Server_VerifyLock() == OK)) { if ((arg == GET_FLAG) || (Server_VerifyLock() == OK)) {
if (arg > MAX_STORAGE_CELL_VAL) { if (arg > getMaxStoragecellStart()) {
ret = FAIL; ret = FAIL;
strcpy(mess, "Max Storage cell number should not exceed 15\n"); sprintf(mess, "Max Storage cell number should not exceed %d\n", getMaxStoragecellStart());
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} else { } else {
retval = selectStoragecellStart(arg); retval = selectStoragecellStart(arg);

View File

@ -1144,7 +1144,7 @@ class Detector {
Result<int> getNumberOfAdditionalStorageCells(Positions pos = {}) const; Result<int> getNumberOfAdditionalStorageCells(Positions pos = {}) const;
/** [Jungfrau] Advanced \n /** [Jungfrau] Advanced \n
* Options: 0 - 15. Default: 0. \n * Only for chipv1.0. Options: 0 - 15. Default: 0. \n
* The #images = #frames x #triggers x (#storagecells + 1) */ * The #images = #frames x #triggers x (#storagecells + 1) */
void setNumberOfAdditionalStorageCells(int value); void setNumberOfAdditionalStorageCells(int value);
@ -1152,7 +1152,7 @@ class Detector {
Result<int> getStorageCellStart(Positions pos = {}) const; Result<int> getStorageCellStart(Positions pos = {}) const;
/** [Jungfrau] Advanced. Sets the storage cell storing the first acquisition /** [Jungfrau] Advanced. Sets the storage cell storing the first acquisition
* of the series. Options: 0-15. Default: 15. * of the series. Options: 0-max. max is 15 (default) for chipv1.0 and 3 (default) for chipv1.1.
*/ */
void setStorageCellStart(int cell, Positions pos = {}); void setStorageCellStart(int cell, Positions pos = {});
@ -1160,7 +1160,8 @@ class Detector {
Result<ns> getStorageCellDelay(Positions pos = {}) const; Result<ns> getStorageCellDelay(Positions pos = {}) const;
/** [Jungfrau] Advanced \n Additional time delay between 2 consecutive /** [Jungfrau] Advanced \n Additional time delay between 2 consecutive
* exposures in burst mode. \n Options: (0-1638375 ns (resolution of 25ns) * exposures in burst mode. \n Options: (0-1638375 ns (resolution of 25ns)\n
* Only applicable for chipv1.0.
*/ */
void setStorageCellDelay(ns value, Positions pos = {}); void setStorageCellDelay(ns value, Positions pos = {});
///@{ ///@{

View File

@ -1850,21 +1850,21 @@ class CmdProxy {
INTEGER_COMMAND_SET_NOID_GET_ID( INTEGER_COMMAND_SET_NOID_GET_ID(
storagecells, getNumberOfAdditionalStorageCells, storagecells, getNumberOfAdditionalStorageCells,
setNumberOfAdditionalStorageCells, StringTo<int>, setNumberOfAdditionalStorageCells, StringTo<int>,
"[0-15]\n\t[Jungfrau] Number of additional storage cells. Default is " "[0-15]\n\t[Jungfrau] Only for chipv1.0. Number of additional storage cells. Default is "
"0. For advanced users only. \n\tThe #images = #frames x #triggers x " "0. For advanced users only. \n\tThe #images = #frames x #triggers x "
"(#storagecells + 1)."); "(#storagecells + 1).");
INTEGER_COMMAND_VEC_ID( INTEGER_COMMAND_VEC_ID(
storagecell_start, getStorageCellStart, setStorageCellStart, storagecell_start, getStorageCellStart, setStorageCellStart,
StringTo<int>, StringTo<int>,
"[0-15]\n\t[Jungfrau] Storage cell that stores the first acquisition " "[0-max]\n\t[Jungfrau] Storage cell that stores the first acquisition "
"of the series. Default is 15. For advanced users only."); "of the series. max is 15 (default) for chipv1.0 and 3 (default) for chipv1.1. For advanced users only.");
TIME_COMMAND( TIME_COMMAND(
storagecell_delay, getStorageCellDelay, setStorageCellDelay, storagecell_delay, getStorageCellDelay, setStorageCellDelay,
"[duration (0-1638375 ns)] [(optional unit) ns|us|ms|s]\n\t[Jungfrau] " "[duration (0-1638375 ns)] [(optional unit) ns|us|ms|s]\n\t[Jungfrau] "
"Additional time delay between 2 consecutive exposures in burst mode " "Additional time delay between 2 consecutive exposures in burst mode "
"(resolution of 25ns). For advanced users only."); "(resolution of 25ns). Only applicable for chipv1.0. For advanced users only.");
/* Gotthard Specific */ /* Gotthard Specific */
TIME_GET_COMMAND(exptimel, getExptimeLeft, TIME_GET_COMMAND(exptimel, getExptimeLeft,

View File

@ -288,30 +288,38 @@ TEST_CASE("storagecells", "[.cmd]") {
CmdProxy proxy(&det); CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
if (det_type == defs::JUNGFRAU) { if (det_type == defs::JUNGFRAU) {
auto prev_val = det.getNumberOfAdditionalStorageCells().tsquash( // chip version 1.0
"inconsistent #additional storage cells to test"); if (det.getChipVersion().squash()*10 == 10) {
{ auto prev_val = det.getNumberOfAdditionalStorageCells().tsquash(
std::ostringstream oss; "inconsistent #additional storage cells to test");
proxy.Call("storagecells", {"1"}, -1, PUT, oss); {
REQUIRE(oss.str() == "storagecells 1\n"); std::ostringstream oss;
proxy.Call("storagecells", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "storagecells 1\n");
}
{
std::ostringstream oss;
proxy.Call("storagecells", {"15"}, -1, PUT, oss);
REQUIRE(oss.str() == "storagecells 15\n");
}
{
std::ostringstream oss;
proxy.Call("storagecells", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "storagecells 0\n");
}
{
std::ostringstream oss;
proxy.Call("storagecells", {}, -1, GET, oss);
REQUIRE(oss.str() == "storagecells 0\n");
}
REQUIRE_THROWS(proxy.Call("storagecells", {"16"}, -1, PUT));
det.setNumberOfAdditionalStorageCells(prev_val);
} }
{ // chip version 1.1
std::ostringstream oss; else {
proxy.Call("storagecells", {"15"}, -1, PUT, oss); // cannot set number of addl. storage cells
REQUIRE(oss.str() == "storagecells 15\n"); REQUIRE_THROWS(proxy.Call("storagecells", {"1"}, -1, PUT));
} }
{
std::ostringstream oss;
proxy.Call("storagecells", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "storagecells 0\n");
}
{
std::ostringstream oss;
proxy.Call("storagecells", {}, -1, GET, oss);
REQUIRE(oss.str() == "storagecells 0\n");
}
REQUIRE_THROWS(proxy.Call("storagecells", {"16"}, -1, PUT));
det.setNumberOfAdditionalStorageCells(prev_val);
} else { } else {
REQUIRE_THROWS(proxy.Call("storagecells", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("storagecells", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("storagecells", {"0"}, -1, PUT)); REQUIRE_THROWS(proxy.Call("storagecells", {"0"}, -1, PUT));
@ -329,11 +337,20 @@ TEST_CASE("storagecell_start", "[.cmd]") {
proxy.Call("storagecell_start", {"1"}, -1, PUT, oss); proxy.Call("storagecell_start", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "storagecell_start 1\n"); REQUIRE(oss.str() == "storagecell_start 1\n");
} }
{ // chip version 1.0
if (det.getChipVersion().squash()*10 == 10) {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("storagecell_start", {"15"}, -1, PUT, oss); proxy.Call("storagecell_start", {"15"}, -1, PUT, oss);
REQUIRE(oss.str() == "storagecell_start 15\n"); REQUIRE(oss.str() == "storagecell_start 15\n");
} }
// chip version 1.1
else {
// max is 3
REQUIRE_THROWS(proxy.Call("storagecell_start", {"15"}, -1, PUT));
std::ostringstream oss;
proxy.Call("storagecell_start", {"3"}, -1, PUT, oss);
REQUIRE(oss.str() == "storagecell_start 3\n");
}
{ {
std::ostringstream oss; std::ostringstream oss;
proxy.Call("storagecell_start", {"0"}, -1, PUT, oss); proxy.Call("storagecell_start", {"0"}, -1, PUT, oss);
@ -359,25 +376,33 @@ TEST_CASE("storagecell_delay", "[.cmd]") {
CmdProxy proxy(&det); CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
if (det_type == defs::JUNGFRAU) { if (det_type == defs::JUNGFRAU) {
auto prev_val = det.getStorageCellDelay(); // chip version 1.0
{ if (det.getChipVersion().squash()*10 == 10) {
std::ostringstream oss; auto prev_val = det.getStorageCellDelay();
proxy.Call("storagecell_delay", {"1.62ms"}, -1, PUT, oss); {
REQUIRE(oss.str() == "storagecell_delay 1.62ms\n"); std::ostringstream oss;
proxy.Call("storagecell_delay", {"1.62ms"}, -1, PUT, oss);
REQUIRE(oss.str() == "storagecell_delay 1.62ms\n");
}
{
std::ostringstream oss;
proxy.Call("storagecell_delay", {}, -1, GET, oss);
REQUIRE(oss.str() == "storagecell_delay 1.62ms\n");
}
{
std::ostringstream oss;
proxy.Call("storagecell_delay", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "storagecell_delay 0\n");
}
REQUIRE_THROWS(proxy.Call("storagecell_delay", {"1638376ns"}, -1, PUT));
for (int i = 0; i != det.size(); ++i) {
det.setStorageCellDelay(prev_val[i], {i});
}
} }
{ // chip version 1.1
std::ostringstream oss; else {
proxy.Call("storagecell_delay", {}, -1, GET, oss); // cannot set storage cell delay
REQUIRE(oss.str() == "storagecell_delay 1.62ms\n"); REQUIRE_THROWS(proxy.Call("storagecell_delay", {"1.62ms"}, -1, PUT));
}
{
std::ostringstream oss;
proxy.Call("storagecell_delay", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "storagecell_delay 0\n");
}
REQUIRE_THROWS(proxy.Call("storagecell_delay", {"1638376ns"}, -1, PUT));
for (int i = 0; i != det.size(); ++i) {
det.setStorageCellDelay(prev_val[i], {i});
} }
} else { } else {
REQUIRE_THROWS(proxy.Call("storagecell_delay", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("storagecell_delay", {}, -1, GET));