From 4c3c5e5db5d31802efa38e1cc0d90909a545bedb Mon Sep 17 00:00:00 2001
From: Juliano Murari <juliano.murari@ess.eu>
Date: Tue, 26 Jul 2022 16:15:43 +0200
Subject: [PATCH] Add auto flat top enable PV per ACCT channel

---
 sis8300bcmApp/Db/sis8300bcm-acct.template | 21 +++++++++++++++++++++
 sis8300bcmApp/src/sis8300bcm.cpp          | 12 ++++++++++++
 sis8300bcmApp/src/sis8300bcm.h            |  2 ++
 vendor/ess/lib/sis8300bcm_reg.h           |  1 +
 vendor/ess/lib/sis8300drvbcm.c            | 20 ++++++++++++++++++++
 vendor/ess/lib/sis8300drvbcm.h            |  2 ++
 6 files changed, 58 insertions(+)

diff --git a/sis8300bcmApp/Db/sis8300bcm-acct.template b/sis8300bcmApp/Db/sis8300bcm-acct.template
index 303c3c8..a8c6645 100644
--- a/sis8300bcmApp/Db/sis8300bcm-acct.template
+++ b/sis8300bcmApp/Db/sis8300bcm-acct.template
@@ -1243,6 +1243,27 @@ record(ai, "$(P)$(R)AutoFlatTopEndR")
     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 d5bd1e6..a9b1434 100644
--- a/sis8300bcmApp/src/sis8300bcm.cpp
+++ b/sis8300bcmApp/src/sis8300bcm.cpp
@@ -273,6 +273,7 @@ sis8300bcm::sis8300bcm(const char *portName, const char *devicePath,
     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);
@@ -942,6 +943,12 @@ int sis8300bcm::readbackParameters()
             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);
@@ -1942,6 +1949,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) {
diff --git a/sis8300bcmApp/src/sis8300bcm.h b/sis8300bcmApp/src/sis8300bcm.h
index 48ba603..7cccd91 100644
--- a/sis8300bcmApp/src/sis8300bcm.h
+++ b/sis8300bcmApp/src/sis8300bcm.h
@@ -169,6 +169,7 @@
 #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"
@@ -391,6 +392,7 @@ protected:
     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 1a30b77..b7d6db9 100644
--- a/vendor/ess/lib/sis8300bcm_reg.h
+++ b/vendor/ess/lib/sis8300bcm_reg.h
@@ -150,6 +150,7 @@ extern "C" {
 #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 419c587..65deb80 100644
--- a/vendor/ess/lib/sis8300drvbcm.c
+++ b/vendor/ess/lib/sis8300drvbcm.c
@@ -2869,6 +2869,26 @@ int sis8300drvbcm_get_channel_auto_flattop_end(sis8300drv_usr *sisuser, unsigned
     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 9e7e84a..4a96739 100644
--- a/vendor/ess/lib/sis8300drvbcm.h
+++ b/vendor/ess/lib/sis8300drvbcm.h
@@ -218,6 +218,8 @@ int sis8300drvbcm_set_channel_auto_flattop_start(sis8300drv_usr *sisuser, unsign
 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);
-- 
GitLab