From 66217b15fe2a0caae417a91e7d6ab0d0f6773b7e Mon Sep 17 00:00:00 2001
From: Juliano Murari <juliano.murari@ess.eu>
Date: Fri, 30 Sep 2022 10:05:16 +0200
Subject: [PATCH] Extend Beam Absence to 10 channels

---
 sis8300bcmApp/Db/sis8300bcm.template | 119 +++++++++++++++++++++++++++
 sis8300bcmApp/src/sis8300bcm.cpp     |  86 ++++++++++++++++++-
 sis8300bcmApp/src/sis8300bcm.h       |  14 ++++
 vendor/ess/lib/sis8300drvbcm.c       |   6 +-
 4 files changed, 220 insertions(+), 5 deletions(-)

diff --git a/sis8300bcmApp/Db/sis8300bcm.template b/sis8300bcmApp/Db/sis8300bcm.template
index 6eb3871..6624c0b 100644
--- a/sis8300bcmApp/Db/sis8300bcm.template
+++ b/sis8300bcmApp/Db/sis8300bcm.template
@@ -737,3 +737,122 @@ record(bi, "$(P)$(R)BeamAbsenceMask-Ch2R")
     field(ZNAM, "Disabled")
     field(ONAM, "Enabled")
 }
+record(bo, "$(P)$(R)BeamAbsenceMask-Ch3")
+{
+    field(DTYP, "asynInt32")
+    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.BEAM_ABSENCE_CHANNEL_3")
+    field(ZNAM, "Disable")
+    field(ONAM, "Enable")
+    field(ASG,  "critical")
+    info(autosaveFields, "VAL")
+}
+record(bi, "$(P)$(R)BeamAbsenceMask-Ch3R")
+{
+    field(DTYP, "asynInt32")
+    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.BEAM_ABSENCE_CHANNEL_3")
+    field(SCAN, "I/O Intr")
+    field(ZNAM, "Disabled")
+    field(ONAM, "Enabled")
+}
+record(bo, "$(P)$(R)BeamAbsenceMask-Ch4")
+{
+    field(DTYP, "asynInt32")
+    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.BEAM_ABSENCE_CHANNEL_4")
+    field(ZNAM, "Disable")
+    field(ONAM, "Enable")
+    field(ASG,  "critical")
+    info(autosaveFields, "VAL")
+}
+record(bi, "$(P)$(R)BeamAbsenceMask-Ch4R")
+{
+    field(DTYP, "asynInt32")
+    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.BEAM_ABSENCE_CHANNEL_4")
+    field(SCAN, "I/O Intr")
+    field(ZNAM, "Disabled")
+    field(ONAM, "Enabled")
+}
+record(bo, "$(P)$(R)BeamAbsenceMask-Ch5")
+{
+    field(DTYP, "asynInt32")
+    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.BEAM_ABSENCE_CHANNEL_5")
+    field(ZNAM, "Disable")
+    field(ONAM, "Enable")
+    field(ASG,  "critical")
+    info(autosaveFields, "VAL")
+}
+record(bi, "$(P)$(R)BeamAbsenceMask-Ch5R")
+{
+    field(DTYP, "asynInt32")
+    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.BEAM_ABSENCE_CHANNEL_5")
+    field(SCAN, "I/O Intr")
+    field(ZNAM, "Disabled")
+    field(ONAM, "Enabled")
+}
+record(bo, "$(P)$(R)BeamAbsenceMask-Ch6")
+{
+    field(DTYP, "asynInt32")
+    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.BEAM_ABSENCE_CHANNEL_6")
+    field(ZNAM, "Disable")
+    field(ONAM, "Enable")
+    field(ASG,  "critical")
+    info(autosaveFields, "VAL")
+}
+record(bi, "$(P)$(R)BeamAbsenceMask-Ch6R")
+{
+    field(DTYP, "asynInt32")
+    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.BEAM_ABSENCE_CHANNEL_6")
+    field(SCAN, "I/O Intr")
+    field(ZNAM, "Disabled")
+    field(ONAM, "Enabled")
+}
+record(bo, "$(P)$(R)BeamAbsenceMask-Ch7")
+{
+    field(DTYP, "asynInt32")
+    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.BEAM_ABSENCE_CHANNEL_7")
+    field(ZNAM, "Disable")
+    field(ONAM, "Enable")
+    field(ASG,  "critical")
+    info(autosaveFields, "VAL")
+}
+record(bi, "$(P)$(R)BeamAbsenceMask-Ch7R")
+{
+    field(DTYP, "asynInt32")
+    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.BEAM_ABSENCE_CHANNEL_7")
+    field(SCAN, "I/O Intr")
+    field(ZNAM, "Disabled")
+    field(ONAM, "Enabled")
+}
+record(bo, "$(P)$(R)BeamAbsenceMask-Ch8")
+{
+    field(DTYP, "asynInt32")
+    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.BEAM_ABSENCE_CHANNEL_8")
+    field(ZNAM, "Disable")
+    field(ONAM, "Enable")
+    field(ASG,  "critical")
+    info(autosaveFields, "VAL")
+}
+record(bi, "$(P)$(R)BeamAbsenceMask-Ch8R")
+{
+    field(DTYP, "asynInt32")
+    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.BEAM_ABSENCE_CHANNEL_8")
+    field(SCAN, "I/O Intr")
+    field(ZNAM, "Disabled")
+    field(ONAM, "Enabled")
+}
+record(bo, "$(P)$(R)BeamAbsenceMask-Ch9")
+{
+    field(DTYP, "asynInt32")
+    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.BEAM_ABSENCE_CHANNEL_9")
+    field(ZNAM, "Disable")
+    field(ONAM, "Enable")
+    field(ASG,  "critical")
+    info(autosaveFields, "VAL")
+}
+record(bi, "$(P)$(R)BeamAbsenceMask-Ch9R")
+{
+    field(DTYP, "asynInt32")
+    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))BCM.BEAM_ABSENCE_CHANNEL_9")
+    field(SCAN, "I/O Intr")
+    field(ZNAM, "Disabled")
+    field(ONAM, "Enabled")
+}
diff --git a/sis8300bcmApp/src/sis8300bcm.cpp b/sis8300bcmApp/src/sis8300bcm.cpp
index b496e11..3606c6e 100644
--- a/sis8300bcmApp/src/sis8300bcm.cpp
+++ b/sis8300bcmApp/src/sis8300bcm.cpp
@@ -188,6 +188,13 @@ sis8300bcm::sis8300bcm(const char *portName, const char *devicePath,
     createParam(BCMBeamAbsenceChannel0String,               asynParamInt32,     &BCMBeamAbsenceChannel0);
     createParam(BCMBeamAbsenceChannel1String,               asynParamInt32,     &BCMBeamAbsenceChannel1);
     createParam(BCMBeamAbsenceChannel2String,               asynParamInt32,     &BCMBeamAbsenceChannel2);
+    createParam(BCMBeamAbsenceChannel3String,               asynParamInt32,     &BCMBeamAbsenceChannel3);
+    createParam(BCMBeamAbsenceChannel4String,               asynParamInt32,     &BCMBeamAbsenceChannel4);
+    createParam(BCMBeamAbsenceChannel5String,               asynParamInt32,     &BCMBeamAbsenceChannel5);
+    createParam(BCMBeamAbsenceChannel6String,               asynParamInt32,     &BCMBeamAbsenceChannel6);
+    createParam(BCMBeamAbsenceChannel7String,               asynParamInt32,     &BCMBeamAbsenceChannel7);
+    createParam(BCMBeamAbsenceChannel8String,               asynParamInt32,     &BCMBeamAbsenceChannel8);
+    createParam(BCMBeamAbsenceChannel9String,               asynParamInt32,     &BCMBeamAbsenceChannel9);
     // ACCT block, channel specific
     createParam(BCMAcctTriggerSourceString,                 asynParamInt32,     &BCMAcctTriggerSource);
     createParam(BCMAcctPulseChargeString,                   asynParamFloat64,   &BCMAcctPulseCharge);
@@ -689,20 +696,60 @@ int sis8300bcm::readbackParameters()
         return ret;
     }
     setIntegerParam(BCMBeamAbsenceChannel0, uintValue);
-
     ret = sis8300drvbcm_get_beam_absence_signals(mDeviceHandle, 1, &uintValue);
     if (ret) {
         asynPrintError(pasynUserSelf, "sis8300drvbcm_get_beam_absence_signals bit 1 returned %d", ret);
         return ret;
     }
     setIntegerParam(BCMBeamAbsenceChannel1, uintValue);
-
     ret = sis8300drvbcm_get_beam_absence_signals(mDeviceHandle, 2, &uintValue);
     if (ret) {
         asynPrintError(pasynUserSelf, "sis8300drvbcm_get_beam_absence_signals bit 2 returned %d", ret);
         return ret;
     }
     setIntegerParam(BCMBeamAbsenceChannel2, uintValue);
+    ret = sis8300drvbcm_get_beam_absence_signals(mDeviceHandle, 3, &uintValue);
+    if (ret) {
+        asynPrintError(pasynUserSelf, "sis8300drvbcm_get_beam_absence_signals bit 3 returned %d", ret);
+        return ret;
+    }
+    setIntegerParam(BCMBeamAbsenceChannel3, uintValue);
+    ret = sis8300drvbcm_get_beam_absence_signals(mDeviceHandle, 4, &uintValue);
+    if (ret) {
+        asynPrintError(pasynUserSelf, "sis8300drvbcm_get_beam_absence_signals bit 4 returned %d", ret);
+        return ret;
+    }
+    setIntegerParam(BCMBeamAbsenceChannel4, uintValue);
+    ret = sis8300drvbcm_get_beam_absence_signals(mDeviceHandle, 5, &uintValue);
+    if (ret) {
+        asynPrintError(pasynUserSelf, "sis8300drvbcm_get_beam_absence_signals bit 5 returned %d", ret);
+        return ret;
+    }
+    setIntegerParam(BCMBeamAbsenceChannel5, uintValue);
+    ret = sis8300drvbcm_get_beam_absence_signals(mDeviceHandle, 6, &uintValue);
+    if (ret) {
+        asynPrintError(pasynUserSelf, "sis8300drvbcm_get_beam_absence_signals bit 6 returned %d", ret);
+        return ret;
+    }
+    setIntegerParam(BCMBeamAbsenceChannel6, uintValue);
+    ret = sis8300drvbcm_get_beam_absence_signals(mDeviceHandle, 7, &uintValue);
+    if (ret) {
+        asynPrintError(pasynUserSelf, "sis8300drvbcm_get_beam_absence_signals bit 7 returned %d", ret);
+        return ret;
+    }
+    setIntegerParam(BCMBeamAbsenceChannel7, uintValue);
+    ret = sis8300drvbcm_get_beam_absence_signals(mDeviceHandle, 8, &uintValue);
+    if (ret) {
+        asynPrintError(pasynUserSelf, "sis8300drvbcm_get_beam_absence_signals bit 8 returned %d", ret);
+        return ret;
+    }
+    setIntegerParam(BCMBeamAbsenceChannel8, uintValue);
+    ret = sis8300drvbcm_get_beam_absence_signals(mDeviceHandle, 9, &uintValue);
+    if (ret) {
+        asynPrintError(pasynUserSelf, "sis8300drvbcm_get_beam_absence_signals bit 9 returned %d", ret);
+        return ret;
+    }
+    setIntegerParam(BCMBeamAbsenceChannel9, uintValue);
 
     // readback channel configuration parameters
     for (int addr = 0; addr < SIS8300BCM_NUM_CHANNELS; addr++) {
@@ -1795,6 +1842,41 @@ asynStatus sis8300bcm::writeInt32(asynUser *pasynUser, epicsInt32 value)
         if (ret) {
             asynPrintError(pasynUser, "sis8300drvbcm_set_beam_absence_signals bit 2 returned %d", ret);
         }
+    } else if (function == BCMBeamAbsenceChannel3) {
+        ret = sis8300drvbcm_set_beam_absence_signals(mDeviceHandle, 3, value);
+        if (ret) {
+            asynPrintError(pasynUser, "sis8300drvbcm_set_beam_absence_signals bit 3 returned %d", ret);
+        }
+    } else if (function == BCMBeamAbsenceChannel4) {
+        ret = sis8300drvbcm_set_beam_absence_signals(mDeviceHandle, 4, value);
+        if (ret) {
+            asynPrintError(pasynUser, "sis8300drvbcm_set_beam_absence_signals bit 4 returned %d", ret);
+        }
+    } else if (function == BCMBeamAbsenceChannel5) {
+        ret = sis8300drvbcm_set_beam_absence_signals(mDeviceHandle, 5, value);
+        if (ret) {
+            asynPrintError(pasynUser, "sis8300drvbcm_set_beam_absence_signals bit 5 returned %d", ret);
+        }
+    } else if (function == BCMBeamAbsenceChannel6) {
+        ret = sis8300drvbcm_set_beam_absence_signals(mDeviceHandle, 6, value);
+        if (ret) {
+            asynPrintError(pasynUser, "sis8300drvbcm_set_beam_absence_signals bit 6 returned %d", ret);
+        }
+    } else if (function == BCMBeamAbsenceChannel7) {
+        ret = sis8300drvbcm_set_beam_absence_signals(mDeviceHandle, 7, value);
+        if (ret) {
+            asynPrintError(pasynUser, "sis8300drvbcm_set_beam_absence_signals bit 7 returned %d", ret);
+        }
+    } else if (function == BCMBeamAbsenceChannel8) {
+        ret = sis8300drvbcm_set_beam_absence_signals(mDeviceHandle, 8, value);
+        if (ret) {
+            asynPrintError(pasynUser, "sis8300drvbcm_set_beam_absence_signals bit 8 returned %d", ret);
+        }
+    } else if (function == BCMBeamAbsenceChannel9) {
+        ret = sis8300drvbcm_set_beam_absence_signals(mDeviceHandle, 9, value);
+        if (ret) {
+            asynPrintError(pasynUser, "sis8300drvbcm_set_beam_absence_signals bit 9 returned %d", ret);
+        }
     } else if (function == SIS8300TriggerSource || function == SIS8300TriggerExternalLine) {
         // override generic trigger source/line handling from sis8300
     } else if (function == BCMAcctDroopCompensating) {
diff --git a/sis8300bcmApp/src/sis8300bcm.h b/sis8300bcmApp/src/sis8300bcm.h
index a1a8940..9aab918 100644
--- a/sis8300bcmApp/src/sis8300bcm.h
+++ b/sis8300bcmApp/src/sis8300bcm.h
@@ -84,6 +84,13 @@
 #define BCMBeamAbsenceChannel0String                 "BCM.BEAM_ABSENCE_CHANNEL_0"
 #define BCMBeamAbsenceChannel1String                 "BCM.BEAM_ABSENCE_CHANNEL_1"
 #define BCMBeamAbsenceChannel2String                 "BCM.BEAM_ABSENCE_CHANNEL_2"
+#define BCMBeamAbsenceChannel3String                 "BCM.BEAM_ABSENCE_CHANNEL_3"
+#define BCMBeamAbsenceChannel4String                 "BCM.BEAM_ABSENCE_CHANNEL_4"
+#define BCMBeamAbsenceChannel5String                 "BCM.BEAM_ABSENCE_CHANNEL_5"
+#define BCMBeamAbsenceChannel6String                 "BCM.BEAM_ABSENCE_CHANNEL_6"
+#define BCMBeamAbsenceChannel7String                 "BCM.BEAM_ABSENCE_CHANNEL_7"
+#define BCMBeamAbsenceChannel8String                 "BCM.BEAM_ABSENCE_CHANNEL_8"
+#define BCMBeamAbsenceChannel9String                 "BCM.BEAM_ABSENCE_CHANNEL_9"
 // ACCT block, channel specific
 #define BCMAcctTriggerSourceString                   "BCM.ACCT.TRIGGER_SOURCE"
 #define BCMAcctPulseChargeString                     "BCM.ACCT.PULSE_CHARGE"
@@ -314,6 +321,13 @@ protected:
     int BCMBeamAbsenceChannel0;
     int BCMBeamAbsenceChannel1;
     int BCMBeamAbsenceChannel2;
+    int BCMBeamAbsenceChannel3;
+    int BCMBeamAbsenceChannel4;
+    int BCMBeamAbsenceChannel5;
+    int BCMBeamAbsenceChannel6;
+    int BCMBeamAbsenceChannel7;
+    int BCMBeamAbsenceChannel8;
+    int BCMBeamAbsenceChannel9;
     // ACCT block, channel specific
     int BCMAcctTriggerSource;
     int BCMAcctPulseCharge;
diff --git a/vendor/ess/lib/sis8300drvbcm.c b/vendor/ess/lib/sis8300drvbcm.c
index 908ee3e..666b9c9 100644
--- a/vendor/ess/lib/sis8300drvbcm.c
+++ b/vendor/ess/lib/sis8300drvbcm.c
@@ -149,12 +149,12 @@ int sis8300drvbcm_get_pulse_width_filter(sis8300drv_usr *sisuser, double *width)
 int sis8300drvbcm_set_beam_absence_signals(sis8300drv_usr *sisuser, unsigned int bit, unsigned int mask)
 {
     unsigned int value;
-    // register has lowest 3 bits defined
+    // register has lowest 10 bits defined
     int ret = sis8300drv_reg_read(sisuser, SIS8300BCM_BEAM_ABSENCE_SIGNALS_REG, &value);
     if (ret) {
         return ret;
     }
-    value &= 0x7;
+    value &= 0x3FF;
     // set / clear the desired bit
     if (mask) {
         value |= (1 << bit);
@@ -169,7 +169,7 @@ int sis8300drvbcm_set_beam_absence_signals(sis8300drv_usr *sisuser, unsigned int
 int sis8300drvbcm_get_beam_absence_signals(sis8300drv_usr *sisuser, unsigned int bit, unsigned int *mask)
 {
     unsigned int value;
-    // register has lowest 3 bits defined
+    // register has lowest 10 bits defined
     int ret = sis8300drv_reg_read(sisuser, SIS8300BCM_BEAM_ABSENCE_SIGNALS_REG, &value);
     if (ret) {
         return ret;
-- 
GitLab