adds remaining missing PVs

This commit is contained in:
2025-11-03 09:26:50 +01:00
parent 7bacc716cc
commit a336ca74c9
4 changed files with 152 additions and 167 deletions

View File

@@ -9,86 +9,43 @@
################################################################################ ################################################################################
# Status Variables # Status Variables
# # Trigger a change in status as clearing # Trigger a change in status as clearing
# record(bo, "$(INSTR)$(NAME):T$(CHANNEL)") record(bo, "$(INSTR)$(NAME):T$(CHANNEL)")
# { {
# field(DESC, "Trigger Clearing Status") field(DESC, "Trigger Clearing Status")
# field(VAL, 1) field(VAL, 1)
# field(OUT, "$(INSTR)$(NAME):S$(CHANNEL) PP") field(OUT, "$(INSTR)$(NAME):S$(CHANNEL) PP")
# } }
#
# # Trigger a change in status as value returned to 0 # Trigger a change in status as value returned to 0
# record(seq, "$(INSTR)$(NAME):O$(CHANNEL)") record(seq, "$(INSTR)$(NAME):O$(CHANNEL)")
# { {
# field(DESC, "Trigger Returned to 0 Status") field(DESC, "Trigger Returned to 0 Status")
# field(LNK0, "$(INSTR)$(NAME):S$(CHANNEL) PP") field(LNK0, "$(INSTR)$(NAME):S$(CHANNEL) PP")
# field(DO0, 0) field(DO0, 0)
# field(SELM, "Specified") field(SELM, "Specified")
# field(SELL, "$(INSTR)$(NAME):M$(CHANNEL).VAL") field(SELL, "$(INSTR)$(NAME):M$(CHANNEL).VAL")
# } }
#
# # Current Status of Channel, i.e. is it ready to count? # Current Status of Channel, i.e. is it ready to count?
# record(bi, "$(INSTR)$(NAME):S$(CHANNEL)") record(bi, "$(INSTR)$(NAME):S$(CHANNEL)")
# { {
# field(DESC, "Channel Status") field(DESC, "Channel Status")
# field(VAL, 0) field(VAL, 0)
# field(ZNAM, "OK") field(ZNAM, "OK")
# field(ONAM, "CLEARING") field(ONAM, "CLEARING")
# } }
################################################################################ ################################################################################
# Count Commands # Count Commands
# # Unfortunately, clearing the channels is somewhat complicated as a result of record(longout, "$(INSTR)$(NAME):C$(CHANNEL)")
# # the addition of more channels over time and minimal changes to the underlying interface {
# # field(DESC, "Clear the current channel count")
# # Urs Greuter provided the following explanation: field(DTYP, "asynInt32")
# # field(OUT, "@asyn($(PORT),0,$(TIMEOUT=1)) C_$(CHANNEL)")
# # bei den Befehlen CC r und HC r ist der Parameter r als bit-Maske zu verstehen: field(FLNK, "$(INSTR)$(NAME):T$(CHANNEL)")
# # }
# # Bit0: Zähler Channel 1
# # Bit2: Zähler Channel 2
# # Bit3: Zähler Channel 3
# # Bit4: Zähler Channel 4
# # Bit5: Zähler Channel Timer
# # Bit6: Zähler Channel 5
# # Bit7: Zähler Channel 6
# # Bit8: Zähler Channel 7
# # Bit9: Zähler Channel 8
# #
# # Beispiele:
# # CC 1 setzt den Zähler des Channels 1 zurück
# # CC 4 setzt den Zähler des Channels 3 zurück
# # CC 5 setzt gleichzeitig die Zähler der Channels 1 und 3 zurück
# # CC 16 ist gleichbedeutend wie CT (Timer zurücksetzen)
# # CC 511 setzt gleichzeitig die Zähler aller Kanäle (auch des Timers) zurück.
#
# record(calc, "$(INSTR)$(NAME):BM$(CHANNEL)")
# {
# field(DESC, "Bit Mask for Channel")
# field(INPA, $(CHANNEL))
# field(CALC, "A > 4 ? 2 ^ A : 2 ^ (A-1)")
# field(PINI, "YES")
# }
#
# record(longout, "$(INSTR)$(NAME):C$(CHANNEL)")
# {
# field(DESC, "Clear the current channel count")
# field(DTYP, "stream")
# field(OMSL, "closed_loop")
# field(DOL, "$(INSTR)$(NAME):BM$(CHANNEL) NPP")
# field(OUT, "@... clearChannel($(INSTR)$(NAME):) $(PORT)")
# field(FLNK, "$(INSTR)$(NAME):T$(CHANNEL)")
# }
#
# record(ao,"$(INSTR)$(NAME):THRESH$(CHANNEL)")
# {
# field(DESC, "Sets min rate for counting to proceed")
# field(OMSL, "supervisory")
# field(OROC, "0")
# field(OUT, "@... setMinRate($(INSTR)$(NAME):, $(CHANNEL)) $(PORT)")
# field(DTYP, "stream")
# }
################################################################################ ################################################################################
# Read all monitors values # Read all monitors values

View File

@@ -50,32 +50,32 @@ record(longin, "$(INSTR)$(NAME):CHANNELS")
field(DISP, 1) field(DISP, 1)
} }
# # Trigger a change in status as clearing # Trigger a change in status as clearing
# record(bo, "$(INSTR)$(NAME):ETT") record(bo, "$(INSTR)$(NAME):ETT")
# { {
# field(DESC, "Trigger Clearing Status") field(DESC, "Trigger Clearing Status")
# field(VAL, 1) field(VAL, 1)
# field(OUT, "$(INSTR)$(NAME):ETS PP") field(OUT, "$(INSTR)$(NAME):ETS PP")
# } }
#
# # Trigger a change in status as value returned to 0 # Trigger a change in status as value returned to 0
# record(seq, "$(INSTR)$(NAME):ETO") record(seq, "$(INSTR)$(NAME):ETO")
# { {
# field(DESC, "Trigger Returned to 0 Status") field(DESC, "Trigger Returned to 0 Status")
# field(LNK0, "$(INSTR)$(NAME):ETS PP") field(LNK0, "$(INSTR)$(NAME):ETS PP")
# field(DO0, 0) field(DO0, 0)
# field(SELM, "Specified") field(SELM, "Specified")
# field(SELL, "$(INSTR)$(NAME):ELAPSED-TIME.VAL") field(SELL, "$(INSTR)$(NAME):ELAPSED-TIME.VAL")
# } }
#
# # Current Status of Channel, i.e. is it ready to count? # Current Status of Channel, i.e. is it ready to count?
# record(bi, "$(INSTR)$(NAME):ETS") record(bi, "$(INSTR)$(NAME):ETS")
# { {
# field(DESC, "Channel Status") field(DESC, "Channel Status")
# field(VAL, 0) field(VAL, 0)
# field(ZNAM, "OK") field(ZNAM, "OK")
# field(ONAM, "CLEARING") field(ONAM, "CLEARING")
# } }
################################################################################ ################################################################################
# Count Commands # Count Commands
@@ -116,14 +116,13 @@ record(ao,"$(INSTR)$(NAME):PRESET-TIME")
# field(VAL, "0") # field(VAL, "0")
# field(FLNK, "$(INSTR)$(NAME):RAW-STATUS") # field(FLNK, "$(INSTR)$(NAME):RAW-STATUS")
# } # }
#
# record(longout, "$(INSTR)$(NAME):STOP") record(longout, "$(INSTR)$(NAME):STOP")
# { {
# field(DESC, "Stop the current counting operation") field(DESC, "Stop the current counting operation")
# field(DTYP, "stream") field(DTYP, "asynInt32")
# field(OUT, "@... stopCount($(INSTR)$(NAME):) $(PORT)") field(OUT, "@asyn($(PORT),0,$(TIMEOUT=1)) STOP")
# field(FLNK, "$(INSTR)$(NAME):RAW-STATUS") }
# }
record(longout, "$(INSTR)$(NAME):MONITOR-CHANNEL") record(longout, "$(INSTR)$(NAME):MONITOR-CHANNEL")
{ {
@@ -143,62 +142,53 @@ record(longin, "$(INSTR)$(NAME):MONITOR-CHANNEL_RBV")
field(PINI, "YES") field(PINI, "YES")
} }
# record(calc, "$(INSTR)$(NAME):RATE_MAP") record(ao,"$(INSTR)$(NAME):THRESHOLD")
# { {
# field(DESC, "Want a consistent lowrate pv") field(DESC, "Minimum rate for counting to proceed")
# field(INPA, "$(INSTR)$(NAME):RAW-STATUS.B2 NPP") field(DTYP, "asynInt32")
# field(CALC, "(A=1)?1:0") field(OUT, "@asyn($(PORT),0,$(TIMEOUT=1)) THRESH")
# } field(VAL, "1") # Default Rate
field(DRVL, "1") # Minimum Rate
field(DRVH, "100000") # Maximum Rate
}
# record(ai,"$(INSTR)$(NAME):THRESHOLD_RBV")
# record(ao,"$(INSTR)$(NAME):THRESHOLD") {
# { field(DESC, "Minimum rate for counting to proceed")
# field(DESC, "Minimum rate for counting to proceed") field(EGU, "cts/sec")
# field(VAL, "1") # Default Rate field(DTYP, "asynInt32")
# # Could perhaps still be improved. field(INP, "@asyn($(PORT),0,$(TIMEOUT=1)) THRESH")
# # It seems to only accept whole counts? field(SCAN, "I/O Intr")
# field(DRVL, "1") # Minimum Rate field(PINI, "YES")
# field(DRVH, "100000") # Maximum Rate }
# field(OMSL, "supervisory")
# field(OROC, "0") record(longout,"$(INSTR)$(NAME):THRESHOLD-MONITOR")
# field(OUT, "$(INSTR)$(NAME):THRESHOLD-F PP") {
# } field(DESC, "Channel monitored for minimum rate")
# field(DTYP, "asynInt32")
# record(ai,"$(INSTR)$(NAME):THRESHOLD_RBV") field(OUT, "@asyn($(PORT),0,$(TIMEOUT=1)) THRESH_CH")
# { field(VAL, "1") # Monitor
# field(DESC, "Minimum rate for counting to proceed") field(DRVL, "0") # Smallest Threshold Channel (0 is off)
# field(EGU, "cts/sec") field(DRVH, "$(CHANNELS)") # Largest Threshold Channel
# field(INP, "@... readMinRate($(INSTR)$(NAME):) $(PORT)") }
# field(DTYP, "stream")
# field(SCAN, "1 second") record(longin,"$(INSTR)$(NAME):THRESHOLD-MONITOR_RBV")
# } {
# field(DESC, "Channel monitored for minimum rate")
# record(longout,"$(INSTR)$(NAME):THRESHOLD-MONITOR") field(EGU, "CH")
# { field(DTYP, "asynInt32")
# field(DESC, "Channel monitored for minimum rate") field(INP, "@asyn($(PORT),0,$(TIMEOUT=1)) THRESH_CH")
# field(VAL, "1") # Monitor field(SCAN, "I/O Intr")
# field(DRVL, "0") # Smallest Threshold Channel (0 is off) field(PINI, "YES")
# field(DRVH, "$(CHANNELS)") # Largest Threshold Channel }
# field(OUT, "@... setRateMonitor($(INSTR)$(NAME):) $(PORT)")
# field(DTYP, "stream") record(longout, "$(INSTR)$(NAME):CT")
# } {
# field(DESC, "Clear the timer")
# record(longin,"$(INSTR)$(NAME):THRESHOLD-MONITOR_RBV") field(DTYP, "asynInt32")
# { field(OUT, "@asyn($(PORT),0,$(TIMEOUT=1)) C_TIME")
# field(DESC, "Channel monitored for minimum rate") field(FLNK, "$(INSTR)$(NAME):ETT")
# field(EGU, "CH") }
# field(INP, "@... readRateMonitor($(INSTR)$(NAME):) $(PORT)")
# field(DTYP, "stream")
# field(SCAN, "1 second")
# }
#
# record(longout, "$(INSTR)$(NAME):CT")
# {
# field(DESC, "Clear the timer")
# field(DTYP, "stream")
# field(OUT, "@... clearTimer($(INSTR)$(NAME):) $(PORT)")
# field(FLNK, "$(INSTR)$(NAME):ETT")
# }
################################################################################ ################################################################################
# Read all monitors values # Read all monitors values

View File

@@ -99,6 +99,10 @@ asynStreamGeneratorDriver::asynStreamGeneratorDriver(const char *portName,
createParam(P_ResetString, asynParamInt32, &P_Reset)); createParam(P_ResetString, asynParamInt32, &P_Reset));
status = (asynStatus)(status | setIntegerParam(P_Reset, 0)); status = (asynStatus)(status | setIntegerParam(P_Reset, 0));
status = (asynStatus)(status |
createParam(P_StopString, asynParamInt32, &P_Stop));
status = (asynStatus)(status | setIntegerParam(P_Stop, 0));
status = (asynStatus)(status | createParam(P_CountPresetString, status = (asynStatus)(status | createParam(P_CountPresetString,
asynParamInt32, &P_CountPreset)); asynParamInt32, &P_CountPreset));
status = (asynStatus)(status | setIntegerParam(P_CountPreset, 0)); status = (asynStatus)(status | setIntegerParam(P_CountPreset, 0));
@@ -111,15 +115,32 @@ asynStreamGeneratorDriver::asynStreamGeneratorDriver(const char *portName,
asynParamInt32, &P_ElapsedTime)); asynParamInt32, &P_ElapsedTime));
status = (asynStatus)(status | setIntegerParam(P_ElapsedTime, 0)); status = (asynStatus)(status | setIntegerParam(P_ElapsedTime, 0));
status = (asynStatus)(status | createParam(P_ClearElapsedTimeString,
asynParamInt32, &P_ClearElapsedTime));
status = (asynStatus)(status | setIntegerParam(P_ClearElapsedTime, 0));
status = status =
(asynStatus)(status | createParam(P_MonitorChannelString, (asynStatus)(status | createParam(P_MonitorChannelString,
asynParamInt32, &P_MonitorChannel)); asynParamInt32, &P_MonitorChannel));
status = (asynStatus)(status | setIntegerParam(P_MonitorChannel, 0)); status = (asynStatus)(status | setIntegerParam(P_MonitorChannel, 0));
status =
(asynStatus)(status | createParam(P_ThresholdString,
asynParamInt32, &P_Threshold));
status = (asynStatus)(status | setIntegerParam(P_Threshold, 1));
status =
(asynStatus)(status | createParam(P_ThresholdChannelString,
asynParamInt32, &P_ThresholdChannel));
status = (asynStatus)(status | setIntegerParam(P_ThresholdChannel, 1));
// Create Parameters templated on Channel Number // Create Parameters templated on Channel Number
char pv_name_buffer[100]; char pv_name_buffer[100];
P_Counts = new int[this->num_channels]; P_Counts = new int[this->num_channels];
P_Rates = new int[this->num_channels]; P_Rates = new int[this->num_channels];
P_ClearCounts = new int[this->num_channels];
for (size_t i = 0; i < this->num_channels; ++i) { for (size_t i = 0; i < this->num_channels; ++i) {
memset(pv_name_buffer, 0, 100); memset(pv_name_buffer, 0, 100);
epicsSnprintf(pv_name_buffer, 100, P_CountsString, i); epicsSnprintf(pv_name_buffer, 100, P_CountsString, i);
@@ -134,6 +155,13 @@ asynStreamGeneratorDriver::asynStreamGeneratorDriver(const char *portName,
(asynStatus)(status | createParam(pv_name_buffer, asynParamInt32, (asynStatus)(status | createParam(pv_name_buffer, asynParamInt32,
P_Rates + i)); P_Rates + i));
status = (asynStatus)(status | setIntegerParam(P_Rates[i], 0)); status = (asynStatus)(status | setIntegerParam(P_Rates[i], 0));
memset(pv_name_buffer, 0, 100);
epicsSnprintf(pv_name_buffer, 100, P_ClearCountsString, i);
status =
(asynStatus)(status | createParam(pv_name_buffer, asynParamInt32,
P_ClearCounts + i));
status = (asynStatus)(status | setIntegerParam(P_ClearCounts[i], 0));
} }
if (status) { if (status) {
@@ -145,8 +173,8 @@ asynStreamGeneratorDriver::asynStreamGeneratorDriver(const char *portName,
// Create Events // Create Events
this->pausedEventId = epicsEventCreate(epicsEventEmpty); this->pausedEventId = epicsEventCreate(epicsEventEmpty);
// this->monitorProducer = create_kafka_producer(); this->monitorProducer = create_kafka_producer();
// this->detectorProducer = create_kafka_producer(); this->detectorProducer = create_kafka_producer();
// Setup for Thread Producing Monitor Kafka Events // Setup for Thread Producing Monitor Kafka Events
status = status =

View File

@@ -82,13 +82,18 @@ struct __attribute__((__packed__)) NormalisedDetectorEvent {
#define P_StatusString "STATUS" #define P_StatusString "STATUS"
#define P_ResetString "RESET" #define P_ResetString "RESET"
#define P_StopString "STOP"
#define P_CountPresetString "P_CNT" #define P_CountPresetString "P_CNT"
#define P_TimePresetString "P_TIME" #define P_TimePresetString "P_TIME"
#define P_ElapsedTimeString "TIME" #define P_ElapsedTimeString "TIME"
#define P_ClearElapsedTimeString "C_TIME"
#define P_MonitorChannelString "MONITOR" #define P_MonitorChannelString "MONITOR"
#define P_ThresholdString "THRESH"
#define P_ThresholdChannelString "THRESH_CH"
#define P_CountsString "COUNTS%d" #define P_CountsString "COUNTS%d"
#define P_RateString "RATE%d" #define P_RateString "RATE%d"
#define P_ClearCountsString "C_%d"
/******************************************************************************* /*******************************************************************************
* Stream Generator Coordinating Class * Stream Generator Coordinating Class
@@ -109,12 +114,17 @@ class asynStreamGeneratorDriver : public asynPortDriver {
// Parameter Identifying IDs // Parameter Identifying IDs
int P_Status; int P_Status;
int P_Reset; int P_Reset;
int P_Stop;
int P_CountPreset; int P_CountPreset;
int P_TimePreset; int P_TimePreset;
int P_ElapsedTime; int P_ElapsedTime;
int P_ClearElapsedTime;
int P_MonitorChannel; int P_MonitorChannel;
int P_Threshold;
int P_ThresholdChannel;
int *P_Counts; int *P_Counts;
int *P_Rates; int *P_Rates;
int *P_ClearCounts;
private: private:
asynUser *pasynUDPUser; asynUser *pasynUDPUser;