diff --git a/sis8300bcmApp/Db/sis8300bcm-acct.template b/sis8300bcmApp/Db/sis8300bcm-acct.template index ad6ba957c07152dc78167f063423dda6bceb3b8b..ee41c8a67c2e8b3201356f4e1b2e06d9696a0a29 100644 --- a/sis8300bcmApp/Db/sis8300bcm-acct.template +++ b/sis8300bcmApp/Db/sis8300bcm-acct.template @@ -1193,6 +1193,77 @@ record(ai, "$(P)$(R)BeamOverThresholdR") field(SCAN, "I/O Intr") } +record(ai, "$(P)$(R)TriggerWidthR") +{ + field(DTYP, "asynFloat64") + field(INP, "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.ACCT.TRIGGER_WIDTH") + field(EGU, "ms") + field(SCAN, "I/O Intr") +} + +record(ao, "$(P)$(R)AutoFlatTopStart") +{ + field(DTYP, "asynFloat64") + field(OUT, "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.ACCT.AUTO_FLATTOP_START") + field(EGU, "ns") + field(PREC, "0") + field(VAL, "0.0") + field(PINI, "YES") + field(ASG, "critical") + info(autosaveFields, "VAL") +} + +record(ai, "$(P)$(R)AutoFlatTopStartR") +{ + field(DTYP, "asynFloat64") + field(INP, "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.ACCT.AUTO_FLATTOP_START") + field(EGU, "ns") + field(PREC, "0") + field(SCAN, "I/O Intr") +} + +record(ao, "$(P)$(R)AutoFlatTopEnd") +{ + field(DTYP, "asynFloat64") + field(OUT, "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.ACCT.AUTO_FLATTOP_END") + field(EGU, "ns") + field(PREC, "0") + field(VAL, "0.0") + field(PINI, "YES") + field(ASG, "critical") + info(autosaveFields, "VAL") +} + +record(ai, "$(P)$(R)AutoFlatTopEndR") +{ + field(DTYP, "asynFloat64") + field(INP, "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.ACCT.AUTO_FLATTOP_END") + field(EGU, "ns") + field(PREC, "0") + field(SCAN, "I/O Intr") +} + +record(bo, "$(P)$(R)AutoFlatTopEnable") +{ + field(DTYP, "asynInt32") + field(OUT, "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.ACCT.AUTO_FLATTOP_ENABLE") + field(ZNAM, "Disable") + field(ONAM, "Enable") + field(VAL, "0") + field(PINI, "YES") + field(ASG, "critical") + info(autosaveFields, "VAL") +} + +record(bi, "$(P)$(R)AutoFlatTopEnableR") +{ + field(DTYP, "asynInt32") + field(INP, "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.ACCT.AUTO_FLATTOP_ENABLE") + field(ZNAM, "Disabled") + field(ONAM, "Enabled") + field(SCAN, "I/O Intr") +} + record(ai, "$(P)$(R)LICoefficientR") { field(DTYP, "asynFloat64") diff --git a/sis8300bcmApp/src/sis8300bcm.cpp b/sis8300bcmApp/src/sis8300bcm.cpp index 3ee42ce92712593f529f488d6144a0391c99b448..ca6142ec9c7bea86b1987bb365d5cb69bfd8ff69 100644 --- a/sis8300bcmApp/src/sis8300bcm.cpp +++ b/sis8300bcmApp/src/sis8300bcm.cpp @@ -270,6 +270,10 @@ sis8300bcm::sis8300bcm(const char *portName, const char *devicePath, createParam(BCMAcctBeamAboveThresholdString, asynParamFloat64, &BCMAcctBeamAboveThreshold); createParam(BCMAcctLeakyCoefficientString, asynParamFloat64, &BCMAcctLeakyCoefficient); createParam(BCMAcctLeakyThresholdString, asynParamFloat64, &BCMAcctLeakyThreshold); + createParam(BCMAcctTriggerWidthString, asynParamFloat64, &BCMAcctTriggerWidth); + createParam(BCMAcctAutoFlatTopStartString, asynParamFloat64, &BCMAcctAutoFlatTopStart); + createParam(BCMAcctAutoFlatTopEndString, asynParamFloat64, &BCMAcctAutoFlatTopEnd); + createParam(BCMAcctAutoFlatTopEnableString, asynParamInt32, &BCMAcctAutoFlatTopEnable); // DIFF block, channel specific createParam(BCMDiffSourceAString, asynParamInt32, &BCMDiffSourceA); createParam(BCMDiffSourceBString, asynParamInt32, &BCMDiffSourceB); @@ -922,6 +926,24 @@ int sis8300bcm::readbackParameters() } setDoubleParam(addr, BCMAcctLeakyThreshold, doubleValue); + ret = sis8300drvbcm_get_channel_auto_flattop_start(mDeviceHandle, addr, &doubleValue); + if (ret) { + asynPrintError(pasynUserSelf, "sis8300drvbcm_get_channel_auto_flattop_start returned %d", ret); + return ret; + } + setDoubleParam(addr, BCMAcctAutoFlatTopStart, doubleValue); + ret = sis8300drvbcm_get_channel_auto_flattop_end(mDeviceHandle, addr, &doubleValue); + if (ret) { + asynPrintError(pasynUserSelf, "sis8300drvbcm_get_channel_auto_flattop_end returned %d", ret); + return ret; + } + setDoubleParam(addr, BCMAcctAutoFlatTopEnd, doubleValue); + ret = sis8300drvbcm_get_channel_auto_flattop_enable(mDeviceHandle, addr, &uintValue); + if (ret) { + asynPrintError(pasynUserSelf, "sis8300drvbcm_get_channel_auto_flattop_enable returned %d", ret); + return ret; + } + setIntegerParam(addr, BCMAcctAutoFlatTopEnable, uintValue); ret = sis8300drvbcm_get_channel_droop_rate(mDeviceHandle, addr, &doubleValue); if (ret) { asynPrintError(pasynUserSelf, "sis8300drvbcm_get_channel_droop_rate returned %d", ret); @@ -1141,6 +1163,8 @@ int sis8300bcm::deviceDone() double doubleValue; unsigned int uintValue; double flattopStart, flattopEnd, flattopCharge; + int autoFlattopEnable; + double autoFlattopStart, autoFlattopEnd, triggerWidth; // readout system wide parameters asynPrintDeviceInfo(pasynUserSelf, "readout system wide parameters"); @@ -1238,16 +1262,39 @@ int sis8300bcm::deviceDone() return ret; } setDoubleParam(addr, BCMAcctFlatTopCharge, flattopCharge); - // flat top start and end have been read-back before the start of acquisition - getDoubleParam(addr, BCMAcctFlatTopStart, &flattopStart); - getDoubleParam(addr, BCMAcctFlatTopEnd, &flattopEnd); - // calculate the average current over flattop - ret = sis8300drvbcm_get_channel_flattop_current(mDeviceHandle, addr, flattopEnd - flattopStart, flattopCharge, &doubleValue); + ret = sis8300drvbcm_get_channel_trigger_width(mDeviceHandle, addr, &triggerWidth); if (ret) { - asynPrintError(pasynUserSelf, "sis8300drvbcm_get_channel_flattop_current returned %d", ret); + asynPrintError(pasynUserSelf, "sis8300drvbcm_get_channel_trigger_width returned %d", ret); return ret; } - asynPrintDeviceInfo(pasynUserSelf, "flattop current %f mA", doubleValue); + setDoubleParam(addr, BCMAcctTriggerWidth, triggerWidth); + + // flat top current, check if automatic mode is enabled + getIntegerParam(addr, BCMAcctAutoFlatTopEnable, &autoFlattopEnable); + asynPrintDeviceInfo(pasynUserSelf, "Channel %d auto flattop enable is %d", addr, autoFlattopEnable); + if(autoFlattopEnable){ + // auto flat top start and end have been read-back before the start of acquisition + getDoubleParam(addr, BCMAcctAutoFlatTopStart, &autoFlattopStart); + getDoubleParam(addr, BCMAcctAutoFlatTopEnd, &autoFlattopEnd); + // calculate the average current over automatic flattop (window in ms) + ret = sis8300drvbcm_get_channel_flattop_current(mDeviceHandle, addr, triggerWidth - (autoFlattopStart/1e6) + (autoFlattopEnd/1e6), flattopCharge, &doubleValue); + if (ret) { + asynPrintError(pasynUserSelf, "sis8300drvbcm_get_channel_flattop_current auto returned %d", ret); + return ret; + } + asynPrintDeviceInfo(pasynUserSelf, "Channel %d auto flattop current %f mA", addr, doubleValue); + }else{ + // flat top start and end have been read-back before the start of acquisition + getDoubleParam(addr, BCMAcctFlatTopStart, &flattopStart); + getDoubleParam(addr, BCMAcctFlatTopEnd, &flattopEnd); + // calculate the average current over flattop + ret = sis8300drvbcm_get_channel_flattop_current(mDeviceHandle, addr, flattopEnd - flattopStart, flattopCharge, &doubleValue); + if (ret) { + asynPrintError(pasynUserSelf, "sis8300drvbcm_get_channel_flattop_current returned %d", ret); + return ret; + } + asynPrintDeviceInfo(pasynUserSelf, "Channel %d flattop current %f mA", addr, doubleValue); + } setDoubleParam(addr, BCMAcctFlatTopCurrent, doubleValue); ret = sis8300drvbcm_get_channel_alarm_hold(mDeviceHandle, addr, &uintValue); @@ -1922,6 +1969,11 @@ asynStatus sis8300bcm::writeInt32(asynUser *pasynUser, epicsInt32 value) if (ret) { asynPrintError(pasynUserSelf, "sis8300drvbcm_set_channel_trigger_source returned %d", ret); } + } else if (function == BCMAcctAutoFlatTopEnable) { + ret = sis8300drvbcm_set_channel_auto_flattop_enable(mDeviceHandle, addr, value); + if (ret) { + asynPrintError(pasynUser, "sis8300drvbcm_set_channel_auto_flattop_enable returned %d", ret); + } } else if (function == BCMFiberOutDataSelect) { ret = sis8300drvbcm_set_fiber_out_data_select(mDeviceHandle, addr, value); if (ret) { @@ -2159,6 +2211,16 @@ asynStatus sis8300bcm::writeFloat64(asynUser *pasynUser, epicsFloat64 value) if (ret) { asynPrintError(pasynUser, "sis8300drvbcm_set_pulse_width_filter returned %d", ret); } + } else if (function == BCMAcctAutoFlatTopStart) { + ret = sis8300drvbcm_set_channel_auto_flattop_start(mDeviceHandle, addr, value); + if (ret) { + asynPrintError(pasynUser, "sis8300drvbcm_set_channel_auto_flattop_start returned %d", ret); + } + } else if (function == BCMAcctAutoFlatTopEnd) { + ret = sis8300drvbcm_set_channel_auto_flattop_end(mDeviceHandle, addr, value); + if (ret) { + asynPrintError(pasynUser, "sis8300drvbcm_set_channel_auto_flattop_end returned %d", ret); + } } else { if (function < BCM_FIRST_PARAM) { status = sis8300::writeFloat64(pasynUser, value); diff --git a/sis8300bcmApp/src/sis8300bcm.h b/sis8300bcmApp/src/sis8300bcm.h index aa1a71009c01812a7516a0a73a50e861a7c2a612..d5aadbaa9a01591cef8ba2ebccf14c518dc3ccbe 100644 --- a/sis8300bcmApp/src/sis8300bcm.h +++ b/sis8300bcmApp/src/sis8300bcm.h @@ -166,6 +166,10 @@ #define BCMAcctBeamAboveThresholdString "BCM.ACCT.BEAM_ABOVE_THRESHOLD" #define BCMAcctLeakyCoefficientString "BCM.ACCT.LEAKY_INTEGRATOR_COEFFICIENT" #define BCMAcctLeakyThresholdString "BCM.ACCT.LEAKY_INTEGRATOR_THRESHOLD" +#define BCMAcctTriggerWidthString "BCM.ACCT.TRIGGER_WIDTH" +#define BCMAcctAutoFlatTopStartString "BCM.ACCT.AUTO_FLATTOP_START" +#define BCMAcctAutoFlatTopEndString "BCM.ACCT.AUTO_FLATTOP_END" +#define BCMAcctAutoFlatTopEnableString "BCM.ACCT.AUTO_FLATTOP_ENABLE" // DIFF block, channel specific #define BCMDiffSourceAString "BCM.DIFF.SOURCE_A" #define BCMDiffSourceBString "BCM.DIFF.SOURCE_B" @@ -386,6 +390,10 @@ protected: int BCMAcctBeamAboveThreshold; int BCMAcctLeakyCoefficient; int BCMAcctLeakyThreshold; + int BCMAcctTriggerWidth; + int BCMAcctAutoFlatTopStart; + int BCMAcctAutoFlatTopEnd; + int BCMAcctAutoFlatTopEnable; // DIFF block, channel specific int BCMDiffSourceA; int BCMDiffSourceB; diff --git a/vendor/ess/lib/sis8300bcm_reg.h b/vendor/ess/lib/sis8300bcm_reg.h index 62a96e43e3256d5a156f318f2ba1a6407dcafc8b..4cec2b90b1581a2c05d3dff52d3cb391cf193c4f 100644 --- a/vendor/ess/lib/sis8300bcm_reg.h +++ b/vendor/ess/lib/sis8300bcm_reg.h @@ -147,6 +147,10 @@ extern "C" { #define SIS8300BCM_ACCT_X_FLATTOP_RISING_OFF 0x02F #define SIS8300BCM_ACCT_X_FLATTOP_FALLING_OFF 0x030 #define SIS8300BCM_ACCT_X_BEAM_ABOVE_THRESHOLD_REG 0x034 +#define SIS8300BCM_ACCT_X_TRIGGER_WIDTH_OFF 0x035 +#define SIS8300BCM_ACCT_X_AUTO_FLATTOP_RISING_OFF 0x036 +#define SIS8300BCM_ACCT_X_AUTO_FLATTOP_FALLING_OFF 0x037 +#define SIS8300BCM_ACCT_X_AUTO_FLATTOP_ENABLE_OFF 0x038 /* DIFF block registers diff --git a/vendor/ess/lib/sis8300drvbcm.c b/vendor/ess/lib/sis8300drvbcm.c index 70581cbb98e8bc3c7e0c17a7d9c8cefd7772629d..0602beadcc075f4becae13846ae7a939f959545d 100644 --- a/vendor/ess/lib/sis8300drvbcm.c +++ b/vendor/ess/lib/sis8300drvbcm.c @@ -2792,6 +2792,103 @@ int sis8300drvbcm_get_channel_beam_above_threshold(sis8300drv_usr *sisuser, unsi return ret; } +int sis8300drvbcm_get_channel_trigger_width(sis8300drv_usr *sisuser, unsigned int channel, double *width) +{ + unsigned int reg = SIS8300BCM_CHANNEL_BLOCK_BASE + \ + (SIS8300BCM_CHANNEL_BLOCK_SIZE * channel) + \ + SIS8300BCM_ACCT_BANK_OFF + \ + SIS8300BCM_ACCT_X_TRIGGER_WIDTH_OFF; + unsigned int value; + int ret = sis8300drv_reg_read(sisuser, reg, &value); + if (ret) { + return ret; + } + // register holds 32-bit unsigned value in 'sampling periods', + // function returns double value in miliseconds + *width = 1.0 / s_sampling_frequency * (double)value * 1000.0; + return ret; +} + +// used to control auto flat top start +int sis8300drvbcm_set_channel_auto_flattop_start(sis8300drv_usr *sisuser, unsigned int channel, double start) +{ + unsigned int reg = SIS8300BCM_CHANNEL_BLOCK_BASE + \ + (SIS8300BCM_CHANNEL_BLOCK_SIZE * channel) + \ + SIS8300BCM_ACCT_BANK_OFF + \ + SIS8300BCM_ACCT_X_AUTO_FLATTOP_RISING_OFF; + // register has lowest 13 bits defined + int value = (int)(start / 1000000000.0 * s_sampling_frequency); + // do not mask off higher bits because value is signed value! + int ret = sis8300drv_reg_write(sisuser, reg, (unsigned)value); + return ret; +} +int sis8300drvbcm_get_channel_auto_flattop_start(sis8300drv_usr *sisuser, unsigned int channel, double *start) +{ + unsigned int reg = SIS8300BCM_CHANNEL_BLOCK_BASE + \ + (SIS8300BCM_CHANNEL_BLOCK_SIZE * channel) + \ + SIS8300BCM_ACCT_BANK_OFF + \ + SIS8300BCM_ACCT_X_AUTO_FLATTOP_RISING_OFF; + // register has lowest 13 bits defined + int value; + int ret = sis8300drv_reg_read(sisuser, reg, (unsigned *)&value); + if (ret) { + return ret; + } + // do not mask off higher bits because value is signed value! + *start = (double)value * 1000000000.0 / s_sampling_frequency; + return ret; +} + +// used to control auto flat top end +int sis8300drvbcm_set_channel_auto_flattop_end(sis8300drv_usr *sisuser, unsigned int channel, double end) +{ + unsigned int reg = SIS8300BCM_CHANNEL_BLOCK_BASE + \ + (SIS8300BCM_CHANNEL_BLOCK_SIZE * channel) + \ + SIS8300BCM_ACCT_BANK_OFF + \ + SIS8300BCM_ACCT_X_AUTO_FLATTOP_FALLING_OFF; + // register has lowest 13 bits defined + int value = (int)(end / 1000000000.0 * s_sampling_frequency); + // do not mask off higher bits because value is signed value! + int ret = sis8300drv_reg_write(sisuser, reg, (unsigned)value); + return ret; +} +int sis8300drvbcm_get_channel_auto_flattop_end(sis8300drv_usr *sisuser, unsigned int channel, double *end) +{ + unsigned int reg = SIS8300BCM_CHANNEL_BLOCK_BASE + \ + (SIS8300BCM_CHANNEL_BLOCK_SIZE * channel) + \ + SIS8300BCM_ACCT_BANK_OFF + \ + SIS8300BCM_ACCT_X_AUTO_FLATTOP_FALLING_OFF; + // register has lowest 13 bits defined + int value; + int ret = sis8300drv_reg_read(sisuser, reg, (unsigned *)&value); + if (ret) { + return ret; + } + // do not mask off higher bits because value is signed value! + *end = (double)value * 1000000000.0 / s_sampling_frequency; + return ret; +} + +// used to control auto flat top enable +int sis8300drvbcm_set_channel_auto_flattop_enable(sis8300drv_usr *sisuser, unsigned int channel, unsigned int enable) +{ + unsigned int reg = SIS8300BCM_CHANNEL_BLOCK_BASE + \ + (SIS8300BCM_CHANNEL_BLOCK_SIZE * channel) + \ + SIS8300BCM_ACCT_BANK_OFF + \ + SIS8300BCM_ACCT_X_AUTO_FLATTOP_ENABLE_OFF; + int ret = sis8300drv_reg_write(sisuser, reg, enable); + return ret; +} +int sis8300drvbcm_get_channel_auto_flattop_enable(sis8300drv_usr *sisuser, unsigned int channel, unsigned int *enable) +{ + unsigned int reg = SIS8300BCM_CHANNEL_BLOCK_BASE + \ + (SIS8300BCM_CHANNEL_BLOCK_SIZE * channel) + \ + SIS8300BCM_ACCT_BANK_OFF + \ + SIS8300BCM_ACCT_X_AUTO_FLATTOP_ENABLE_OFF; + int ret = sis8300drv_reg_read(sisuser, reg, enable); + return ret; +} + // used to control fiber out data select int sis8300drvbcm_set_fiber_out_data_select(sis8300drv_usr *sisuser, unsigned int channel, unsigned int selection) { diff --git a/vendor/ess/lib/sis8300drvbcm.h b/vendor/ess/lib/sis8300drvbcm.h index ba82e427cb86dab53d4e978b478db5d9b38aaefb..9bf29033ed97b22ee2cbc12bd2fda05d82050ef3 100644 --- a/vendor/ess/lib/sis8300drvbcm.h +++ b/vendor/ess/lib/sis8300drvbcm.h @@ -213,6 +213,13 @@ int sis8300drvbcm_set_channel_errant_window_end(sis8300drv_usr *sisuser, unsigne int sis8300drvbcm_get_channel_errant_window_end(sis8300drv_usr *sisuser, unsigned int channel, double *end); int sis8300drvbcm_set_channel_beam_above_threshold(sis8300drv_usr *sisuser, unsigned int channel, double threshold); int sis8300drvbcm_get_channel_beam_above_threshold(sis8300drv_usr *sisuser, unsigned int channel, double *threshold); +int sis8300drvbcm_get_channel_trigger_width(sis8300drv_usr *sisuser, unsigned int channel, double *width); +int sis8300drvbcm_set_channel_auto_flattop_start(sis8300drv_usr *sisuser, unsigned int channel, double start); +int sis8300drvbcm_get_channel_auto_flattop_start(sis8300drv_usr *sisuser, unsigned int channel, double *start); +int sis8300drvbcm_set_channel_auto_flattop_end(sis8300drv_usr *sisuser, unsigned int channel, double end); +int sis8300drvbcm_get_channel_auto_flattop_end(sis8300drv_usr *sisuser, unsigned int channel, double *end); +int sis8300drvbcm_set_channel_auto_flattop_enable(sis8300drv_usr *sisuser, unsigned int channel, unsigned int enable); +int sis8300drvbcm_get_channel_auto_flattop_enable(sis8300drv_usr *sisuser, unsigned int channel, unsigned int *enable); int sis8300drvbcm_set_channel_leaky_coefficient(sis8300drv_usr *sisuser, unsigned int channel, double coefficient); int sis8300drvbcm_get_channel_leaky_coefficient(sis8300drv_usr *sisuser, unsigned int channel, double *coefficient); int sis8300drvbcm_set_channel_leaky_threshold(sis8300drv_usr *sisuser, unsigned int channel, double threshold);