From 66792837a6314fc0615aba08b972ac0df45a5379 Mon Sep 17 00:00:00 2001 From: Edward Wall Date: Tue, 18 Nov 2025 14:00:26 +0100 Subject: [PATCH] adds PV for turning Electornics on and off --- Makefile | 2 +- db/correlation_unit.db | 21 +++++++++++++++++++++ scripts/st.cmd | 2 ++ src/asynStreamGeneratorDriver.cpp | 20 ++++++++++++++++++-- src/asynStreamGeneratorDriver.h | 31 ++++++++++++++++++++++++++++++- 5 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 db/correlation_unit.db diff --git a/Makefile b/Makefile index 40dd680..c487cc6 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ REQUIRED+=asyn DBDS += src/asynStreamGeneratorDriver.dbd # DB files to include in the release -TEMPLATES += db/channels.db db/daq_common.db +TEMPLATES += db/channels.db db/daq_common.db db/correlation_unit.db # HEADERS += src/asynStreamGeneratorDriver.h diff --git a/db/correlation_unit.db b/db/correlation_unit.db new file mode 100644 index 0000000..c9457d7 --- /dev/null +++ b/db/correlation_unit.db @@ -0,0 +1,21 @@ +# EPICS Database for streamdevice specific to measurement channels +# +# Macros +# INSTR - Prefix +# NAME - the device name, e.g. EL737 +# PORT - StreamGenerator Port + +################################################################################ +# Status Variables + +record(bo, "$(INSTR)$(NAME):Enable") +{ + field(DESC, "Electronics Status") + field(DTYP, "asynInt32") + field(OUT, "@asyn($(PORT),0,$(TIMEOUT=1)) EN_EL") + field(VAL, 1) + field(ZNAM, "OFF") + field(ONAM, "ON") + field(PINI, 1) + field(SCAN, ".5 second") +} diff --git a/scripts/st.cmd b/scripts/st.cmd index ccd8ffa..f84b078 100755 --- a/scripts/st.cmd +++ b/scripts/st.cmd @@ -24,6 +24,8 @@ drvAsynIPPortConfigure("ASYN_IP_PORT", "127.0.0.1:9071:54321 UDP", 0, 0, 1) # Don't send any kafka messages asynStreamGenerator("ASYN_SG", "ASYN_IP_PORT", 4, 10000, "", "", "", 0, 0) +dbLoadRecords("$(StreamGenerator_DB)correlation_unit.db", "INSTR=$(INSTR), NAME=$(NAME), PORT=ASYN_SG") + dbLoadRecords("$(StreamGenerator_DB)daq_common.db", "INSTR=$(INSTR), NAME=$(NAME), PORT=ASYN_SG, CHANNELS=5") # Monitor Channels diff --git a/src/asynStreamGeneratorDriver.cpp b/src/asynStreamGeneratorDriver.cpp index bda3e18..f862f85 100644 --- a/src/asynStreamGeneratorDriver.cpp +++ b/src/asynStreamGeneratorDriver.cpp @@ -161,6 +161,8 @@ asynStreamGeneratorDriver::asynStreamGeneratorDriver( // Parameter Setup asynStatus status = asynSuccess; + status = createInt32Param(status, P_EnableElectronicsString, + &P_EnableElectronics); status = createInt32Param(status, P_StatusString, &P_Status, STATUS_IDLE); status = createInt32Param(status, P_ResetString, &P_Reset); status = createInt32Param(status, P_StopString, &P_Stop); @@ -439,6 +441,20 @@ asynStatus asynStreamGeneratorDriver::writeInt32(asynUser *pasynUser, } else { return asynError; } + } else if (function == P_EnableElectronics) { + if (value) { + setIntegerParam(function, 1); + CommandHeader ch(start); + std::size_t written; + pasynOctetSyncIO->write(pasynUDPUser, (char *)&ch, sizeof(ch), 1, + &written); + } else { + setIntegerParam(function, 0); + CommandHeader ch(stop); + std::size_t written; + pasynOctetSyncIO->write(pasynUDPUser, (char *)&ch, sizeof(ch), 1, + &written); + } } else { setIntegerParam(function, value); status = (asynStatus)callParamCallbacks(); @@ -522,7 +538,7 @@ void asynStreamGeneratorDriver::normaliseUDP() { epicsInt32 droppedMessages = 0; - const UDPHeader *header; + const DataHeader *header; const DetectorEvent *d_event; const MonitorEvent *m_event; NormalisedEvent ne; @@ -533,7 +549,7 @@ void asynStreamGeneratorDriver::normaliseUDP() { epicsRingBytesGet(this->udpQueue, (char *)buffer, bufferSize); - header = (UDPHeader *)buffer; + header = (DataHeader *)buffer; const std::size_t total_events = (header->BufferLength - 21) / 3; if (header->BufferNumber - lastBufferNumber[header->McpdID] > 1 && diff --git a/src/asynStreamGeneratorDriver.h b/src/asynStreamGeneratorDriver.h index 963a36a..1ff71eb 100644 --- a/src/asynStreamGeneratorDriver.h +++ b/src/asynStreamGeneratorDriver.h @@ -12,7 +12,33 @@ /******************************************************************************* * UDP Packet Definitions */ -struct __attribute__((__packed__)) UDPHeader { +enum CommandId : std::int16_t { reset = 0, start = 1, stop = 2, cont = 3 }; + +struct __attribute__((__packed__)) CommandHeader { + uint16_t BufferLength; + uint16_t BufferType; + uint16_t HeaderLength; + uint16_t BufferNumber; + uint16_t Command; + uint16_t McpdIdStatus; + uint16_t TimeStampLo; + uint16_t TimeStampMid; + uint16_t TimeStampHigh; + uint16_t Checksum; + uint16_t Finalizer; + + CommandHeader(const CommandId commandId) + : BufferLength(10), BufferType(0x8000), HeaderLength(10), + BufferNumber(0), Command(commandId), McpdIdStatus(0), TimeStampLo(0), + TimeStampMid(0), TimeStampHigh(0), Checksum(0), Finalizer(0xffff) { + + Checksum = BufferLength ^ BufferType ^ HeaderLength ^ BufferNumber ^ + Command ^ McpdIdStatus ^ TimeStampLo ^ TimeStampMid ^ + TimeStampHigh; + } +}; + +struct __attribute__((__packed__)) DataHeader { uint16_t BufferLength; uint16_t BufferType; uint16_t HeaderLength; @@ -85,6 +111,8 @@ struct __attribute__((__packed__)) NormalisedEvent { * i.e.e drvInfo strings that are used to identify the parameters */ +constexpr static char P_EnableElectronicsString[]{"EN_EL"}; + constexpr static char P_StatusString[]{"STATUS"}; constexpr static char P_ResetString[]{"RESET"}; constexpr static char P_StopString[]{"STOP"}; @@ -130,6 +158,7 @@ class asynStreamGeneratorDriver : public asynPortDriver { protected: // Parameter Identifying IDs + int P_EnableElectronics; int P_Status; int P_Reset; int P_Stop;