From 7c2aa68fc7a878462f838ab060aa5eee3a65e65b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Martins?= Date: Wed, 29 Nov 2023 15:05:53 +0100 Subject: [PATCH 01/23] Create release candidate for UTAG developments (#2) * First implementation, simple set/get UTAG * Remove I/O Intr link that is not needed * Adding UTAG for each event * Add new getTimeStampUTag method to avoid mutex being locked twice in a row * Minor adjust in UTAG setpoint record name * Fix typo on nanosseconds assignment; convertTS is now template * Overload getTimeStamp; Use define guards to compile for older versions; Clean-up comments and defines * Additional comments and clean-up --- evrApp/Db/evrevent.db | 14 ++++ evrApp/src/Makefile | 2 + evrApp/src/devEvrEvent.cpp | 25 ++++++- evrApp/src/devEvrUtag.cpp | 149 +++++++++++++++++++++++++++++++++++++ evrApp/src/evr/evr.h | 20 +++++ evrApp/src/evrSupport.dbd | 3 + evrMrmApp/src/drvem.cpp | 93 ++++++++++++++++++++++- evrMrmApp/src/drvem.h | 13 +++- 8 files changed, 309 insertions(+), 10 deletions(-) create mode 100644 evrApp/src/devEvrUtag.cpp diff --git a/evrApp/Db/evrevent.db b/evrApp/Db/evrevent.db index a3093879..a54908f1 100644 --- a/evrApp/Db/evrevent.db +++ b/evrApp/Db/evrevent.db @@ -26,3 +26,17 @@ record(calc, "$(EN)Cnt-I") { field(INPA, "$(EN)Cnt-I NPP") field(TSEL, "$(EN)-SP.TIME") } + + +# Mapping between hardware event code and a software database event +# +# Macros: +# EN = record name prefix +# OBJ = EVR devObj name +# CODE = Event code (hardware) +record(int64out, "$(EN)-UTag-SP") { + field(DTYP, "UTAG Source") + field(OUT , "@OBJ=$(OBJ),Code=$(CODE)") + field(VAL , "0") + info(autosaveFields_pass0, "OUT VAL") +} diff --git a/evrApp/src/Makefile b/evrApp/src/Makefile index 9b3fb6da..ce2936f6 100644 --- a/evrApp/src/Makefile +++ b/evrApp/src/Makefile @@ -28,6 +28,8 @@ evr_SRCS += evrGTIF.cpp evr_SRCS += devEvrStringIO.cpp +evr_SRCS += devEvrUtag.cpp + evr_SRCS += devEvrEvent.cpp evr_SRCS += devEvrMapping.cpp diff --git a/evrApp/src/devEvrEvent.cpp b/evrApp/src/devEvrEvent.cpp index 32b2629e..0bf0bb54 100644 --- a/evrApp/src/devEvrEvent.cpp +++ b/evrApp/src/devEvrEvent.cpp @@ -153,7 +153,13 @@ try { post_event(prec->val); if(prec->tse==epicsTimeEventDeviceTime){ - p->evr->getTimeStamp(&prec->time,p->event); + epicsTimeStampUTag ts; + p->evr->getTimeStamp(&ts, p->event); + prec->time.secPastEpoch = ts.secPastEpoch; + prec->time.nsec = ts.nsec; +#ifdef DBR_UTAG + prec->utag = static_cast(ts.utag); +#endif } return 0; @@ -197,9 +203,14 @@ try { #endif if(prec->tse==epicsTimeEventDeviceTime){ - p->evr->getTimeStamp(&prec->time,p->event); + epicsTimeStampUTag ts; + p->evr->getTimeStamp(&ts, p->event); + prec->time.secPastEpoch = ts.secPastEpoch; + prec->time.nsec = ts.nsec; +#ifdef DBR_UTAG + prec->utag = static_cast(ts.utag); +#endif } - return 0; } catch(std::runtime_error& e) { recGblRecordError(S_dev_noDevice, (void*)prec, e.what()); @@ -217,7 +228,13 @@ static long process_event(eventRecord *prec) long ret=0; try { if(prec->tse==epicsTimeEventDeviceTime){ - p->evr->getTimeStamp(&prec->time,p->event); + epicsTimeStampUTag ts; + p->evr->getTimeStamp(&ts, p->event); + prec->time.secPastEpoch = ts.secPastEpoch; + prec->time.nsec = ts.nsec; +#ifdef DBR_UTAG + prec->utag = static_cast(ts.utag); +#endif } return 0; diff --git a/evrApp/src/devEvrUtag.cpp b/evrApp/src/devEvrUtag.cpp new file mode 100644 index 00000000..50ad5a8f --- /dev/null +++ b/evrApp/src/devEvrUtag.cpp @@ -0,0 +1,149 @@ +/*************************************************************************\ +* Copyright (c) 2010 Brookhaven Science Associates, as Operator of +* Brookhaven National Laboratory. +* Copyright (c) 2015 Paul Scherrer Institute (PSI), Villigen, Switzerland +* Copyright (c) 2023 European Spallation Source ERIC (ESS), Lund, Sweden +* mrfioc2 is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* + * Author: Joao Paulo Martins + */ + +#include +#include +#include +#include +#include +#include +#include // For S_dev_* +#include +#include + +#include +#include + +#include "devObj.h" +#include "evr/evr.h" + +#include "linkoptions.h" + +#include +#include + +struct priv { + EVR* evr; + char obj[30]; + int event; + epicsUTag utag; +}; + +static const +linkOptionDef utagdef[] = +{ + linkString (priv, obj , "OBJ" , 1, 0), + linkInt32 (priv, event, "Code", 1, 0), + linkOptionEnd +}; + +static +long add_record(struct dbCommon *prec, struct link* link) +{ + long ret=0; +try { + assert(link->type==INST_IO); + + mrf::auto_ptr p(new priv); + p->utag=0; + p->event=0; + + if (linkOptionsStore(utagdef, p.get(), link->value.instio.string, 0)) + throw std::runtime_error("Couldn't parse link string"); + + mrf::Object *O=mrf::Object::getObject(p->obj); + if(!O) { + errlogPrintf("%s: failed to find object '%s'\n", prec->name, p->obj); + return S_db_errArg; + } + p->evr=dynamic_cast(O); + if(!p->evr) + throw std::runtime_error("Failed to lookup device"); + + prec->dpvt=(void*)p.release(); + + return 0; +} catch(std::runtime_error& e) { + recGblRecordError(S_dev_noDevice, (void*)prec, e.what()); + ret=S_dev_noDevice; +} catch(std::exception& e) { + recGblRecordError(S_db_noMemory, (void*)prec, e.what()); + ret=S_db_noMemory; +} + return ret; +} + +static +long del_record(struct dbCommon *prec) +{ + priv *p=static_cast(prec->dpvt); + long ret=0; + if (!p) return 0; +try { + + prec->dpvt=0; + +} catch(std::runtime_error& e) { + recGblRecordError(S_dev_noDevice, (void*)prec, e.what()); + ret=S_dev_noDevice; +} catch(std::exception& e) { + recGblRecordError(S_db_noMemory, (void*)prec, e.what()); + ret=S_db_noMemory; +} + return ret; +} + +static long process_int64out(int64outRecord *prec) +{ + priv *p=static_cast(prec->dpvt); + long ret=0; +try { + + // Inject the value as the UTAG reference + p->utag = static_cast(prec->val); + p->evr->eventUtagSet(p->event, p->utag); +#ifdef DBR_UTAG + prec->utag = static_cast(p->utag); +#endif + + return 0; +} catch(std::runtime_error& e) { + recGblRecordError(S_dev_noDevice, (void*)prec, e.what()); + ret=S_dev_noDevice; +} catch(std::exception& e) { + recGblRecordError(S_db_noMemory, (void*)prec, e.what()); + ret=S_db_noMemory; +} + return ret; +} + + +static +long add_int64out(struct dbCommon *precord) +{ + return add_record(precord, &((struct int64outRecord*)precord)->out); +} + +dsxt dxtINT64UTAGEVR={add_int64out,del_record}; +static common_dset devINT64UTAGEVR = { + 6, NULL, + dset_cast(&init_dset<&dxtINT64UTAGEVR>), + (DEVSUPFUN) init_record_empty, + (DEVSUPFUN) NULL, + dset_cast(&process_int64out), + NULL }; + +extern "C" { + +epicsExportAddress(dset,devINT64UTAGEVR); + +} diff --git a/evrApp/src/evr/evr.h b/evrApp/src/evr/evr.h index 0cf97556..9a46fb6c 100644 --- a/evrApp/src/evr/evr.h +++ b/evrApp/src/evr/evr.h @@ -34,6 +34,16 @@ enum TSSource { TSSourceDBus4=2 }; +#ifndef DBR_UTAG + typedef epicsUInt32 epicsUTag; +#endif + +struct epicsTimeStampUTag { + epicsUInt32 secPastEpoch; /**< \brief seconds since 0000 Jan 1, 1990 */ + epicsUInt32 nsec; /**< \brief nanoseconds within second */ + epicsUTag utag; /**< \brief user defined tag */ +}; + /**@brief Base interface for EVRs. * * This is the interface which the generic EVR device support @@ -147,6 +157,7 @@ class epicsShareClass EVR : public mrf::ObjectInst *@return false When ts could not be updated */ virtual bool getTimeStamp(epicsTimeStamp *ts,epicsUInt32 event)=0; + virtual bool getTimeStamp(epicsTimeStampUTag *ts,epicsUInt32 event) {return 0;}; /** Returns the current value of the Timestamp Event Counter *@param tks Pointer to be filled with the counter value @@ -191,6 +202,15 @@ class epicsShareClass EVR : public mrf::ObjectInst epicsUInt32 SourceTSraw() const{return (TSSource)SourceTS();}; /*@}*/ + /**\defgroup utagman UTAG Management + * + * Get/Set UTAG value for specific event + */ + /*@{*/ + virtual epicsUTag eventUtag(const epicsUInt32 event) const {return 0;}; + virtual void eventUtagSet(const epicsUInt32 event, epicsUTag tag) {}; + /*@}*/ + private: bus_configuration busConfiguration; }; // class EVR diff --git a/evrApp/src/evrSupport.dbd b/evrApp/src/evrSupport.dbd index eaee7b06..b8db01c1 100644 --- a/evrApp/src/evrSupport.dbd +++ b/evrApp/src/evrSupport.dbd @@ -45,3 +45,6 @@ registrar(EVRTime_Registrar) registrar(ntpShmRegister) driver(ntpShared) variable(mrmGTIFEnable, int) + +# '@C=..., Code=hweventnum' +device(int64out, INST_IO, devINT64UTAGEVR, "UTAG Source") diff --git a/evrMrmApp/src/drvem.cpp b/evrMrmApp/src/drvem.cpp index 44fe9022..b79fdcee 100644 --- a/evrMrmApp/src/drvem.cpp +++ b/evrMrmApp/src/drvem.cpp @@ -826,18 +826,80 @@ EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event) } - if(!convertTS(&ts)) + if(!convertTS(&ts)) return false; *ret = ts; return true; } +bool +EVRMRM::getTimeStamp(epicsTimeStampUTag *ret,epicsUInt32 event) +{ + if(!ret) throw std::runtime_error("Invalid argument"); + epicsTimeStampUTag tstag; + + SCOPED_LOCK(evrLock); + if(timestampValid0 && event<=255) { + // Get time of last event code # + + eventCode *entry=&events[event]; + + // Fail if event is not mapped + if (!entry->interested || + ( entry->last_sec==0 && + entry->last_evt==0) ) + { + return false; + } + + tstag.secPastEpoch=entry->last_sec; + tstag.nsec=entry->last_evt; + tstag.utag=entry->utag; + + + } else { + // Get current absolute time + + epicsUInt32 ctrl=READ32(base, Control); + + // Latch timestamp + WRITE32(base, Control, ctrl|Control_tsltch); + + tstag.secPastEpoch=READ32(base, TSSecLatch); + tstag.nsec=READ32(base, TSEvtLatch); + tstag.utag = 0; + + /* BUG: There was a firmware bug which occasionally + * causes the previous write to fail with a VME bus + * error, and 0 the Control register. + * + * This issues has been fixed in VME firmwares EVRv 5 + * pre2 and EVG v3 pre2. Feb 2011 + */ + epicsUInt32 ctrl2=READ32(base, Control); + if (ctrl2!=ctrl) { // tsltch bit is write-only + printf("Get timestamp: control register write fault. Written: %08x, readback: %08x\n",ctrl,ctrl2); + WRITE32(base, Control, ctrl); + } + + } + + if(!convertTS(&tstag)) + return false; + + *ret = tstag; + return true; +} + + /** @brief In place conversion between raw posix sec+ticks to EPICS sec+nsec. @returns false if conversion failed */ -bool -EVRMRM::convertTS(epicsTimeStamp* ts) +template +bool EVRMRM::convertTS(TimeStampT* ts) { // First validate the input @@ -1361,7 +1423,7 @@ EVRMRM::drain_fifo() active.flushtime.secPastEpoch = evt.last_sec; active.flushtime.nsec = evt.last_evt; - active.ok &= convertTS(&active.flushtime); + active.ok &= convertTS(&active.flushtime); tbuf->doFlush(); } @@ -1563,3 +1625,26 @@ EVRMRM::seconds_tick(void *raw, epicsUInt32) callbackRequest(&evr->timeSrc_cb); } } + +// Get UTAG value for specific event +epicsUTag +EVRMRM::eventUtag(const epicsUInt32 event) const { + if(event==0) return 0; + else if(event>255) throw std::runtime_error("Event code out of range"); + SCOPED_LOCK(evrLock); + + return events[event].utag; +} + +// Set UTAG value for specific event +void +EVRMRM::eventUtagSet(const epicsUInt32 event, epicsUTag tag) { + if(event==0) return; + else if(event>255) throw std::runtime_error("Event code out of range"); + SCOPED_LOCK(evrLock); + + // set UTAG value to particular event + events[event].utag = tag; + return; +} + diff --git a/evrMrmApp/src/drvem.h b/evrMrmApp/src/drvem.h index d4bcc8af..25e7369a 100644 --- a/evrMrmApp/src/drvem.h +++ b/evrMrmApp/src/drvem.h @@ -72,8 +72,12 @@ struct eventCode { size_t waitingfor; bool again; + // UTAG associated to event + epicsUTag utag; + eventCode():owner(0), interested(0), last_sec(0) - ,last_evt(0), waitingfor(0), again(false) + ,last_evt(0), waitingfor(0), again(false), + utag(0) { scanIoInit(&occured); // done_cb - initialized in EVRMRM::EVRMRM() @@ -174,12 +178,14 @@ class epicsShareClass EVRMRM : public mrf::ObjectInst, virtual IOSCANPVT TimeStampValidEvent() const OVERRIDE FINAL {return timestampValidChange;} virtual bool getTimeStamp(epicsTimeStamp *ts,epicsUInt32 event) OVERRIDE FINAL; + virtual bool getTimeStamp(epicsTimeStampUTag *ts,epicsUInt32 event) OVERRIDE FINAL; virtual bool getTicks(epicsUInt32 *tks) OVERRIDE FINAL; virtual IOSCANPVT eventOccurred(epicsUInt32 event) const OVERRIDE FINAL; virtual void eventNotifyAdd(epicsUInt32, eventCallback, void*) OVERRIDE FINAL; virtual void eventNotifyDel(epicsUInt32, eventCallback, void*) OVERRIDE FINAL; - bool convertTS(epicsTimeStamp* ts); + template + bool convertTS(TimeStampT* ts); virtual epicsUInt16 dbus() const OVERRIDE FINAL; @@ -193,6 +199,9 @@ class epicsShareClass EVRMRM : public mrf::ObjectInst, virtual epicsUInt32 FIFOEvtCount() const OVERRIDE FINAL {return count_fifo_events;} virtual epicsUInt32 FIFOLoopCount() const OVERRIDE FINAL {return count_fifo_loops;} + virtual epicsUTag eventUtag(const epicsUInt32 event) const OVERRIDE FINAL; + virtual void eventUtagSet(const epicsUInt32 event, epicsUTag tag) OVERRIDE FINAL; + void enableIRQ(void); bool dcEnabled() const; From 56617202aa770735bb32f38a5037a047c0246249 Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Thu, 30 Nov 2023 13:40:24 +0100 Subject: [PATCH 02/23] fix: Epics base 7 or higher limitations added. --- evrApp/src/Makefile | 5 +++++ evrApp/src/evrSupport.dbd | 3 --- evrApp/src/evrSupportBase7.dbd | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 evrApp/src/evrSupportBase7.dbd diff --git a/evrApp/src/Makefile b/evrApp/src/Makefile index ce2936f6..0da9798e 100644 --- a/evrApp/src/Makefile +++ b/evrApp/src/Makefile @@ -28,7 +28,9 @@ evr_SRCS += evrGTIF.cpp evr_SRCS += devEvrStringIO.cpp +ifdef BASE_7_0 evr_SRCS += devEvrUtag.cpp +endif evr_SRCS += devEvrEvent.cpp evr_SRCS += devEvrMapping.cpp @@ -55,6 +57,9 @@ evrtest_LIBS += evr mrfCommon evrtest_DBD += base.dbd evrtest_DBD += evrSupport.dbd +ifdef BASE_7_0 +evrtest_DBD += evrSupportBase7.dbd +endif ifneq ($(GENERAL_TIME),) evrtest_LIBS += generalTime diff --git a/evrApp/src/evrSupport.dbd b/evrApp/src/evrSupport.dbd index b8db01c1..eaee7b06 100644 --- a/evrApp/src/evrSupport.dbd +++ b/evrApp/src/evrSupport.dbd @@ -45,6 +45,3 @@ registrar(EVRTime_Registrar) registrar(ntpShmRegister) driver(ntpShared) variable(mrmGTIFEnable, int) - -# '@C=..., Code=hweventnum' -device(int64out, INST_IO, devINT64UTAGEVR, "UTAG Source") diff --git a/evrApp/src/evrSupportBase7.dbd b/evrApp/src/evrSupportBase7.dbd new file mode 100644 index 00000000..fd96d74d --- /dev/null +++ b/evrApp/src/evrSupportBase7.dbd @@ -0,0 +1,2 @@ +# '@C=..., Code=hweventnum' +device(int64out, INST_IO, devINT64UTAGEVR, "UTAG Source") From 9cd491c5a69163a9eeb61a5ac9006f3148f971a0 Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Thu, 30 Nov 2023 15:17:20 +0100 Subject: [PATCH 03/23] perf: Removal of the epicsTimeStampUTag. --- evrApp/src/devEvrEvent.cpp | 24 +++++++++--------------- evrApp/src/evr/evr.h | 8 +------- evrMrmApp/src/drvem.cpp | 21 ++++++++++----------- evrMrmApp/src/drvem.h | 2 +- 4 files changed, 21 insertions(+), 34 deletions(-) diff --git a/evrApp/src/devEvrEvent.cpp b/evrApp/src/devEvrEvent.cpp index 0bf0bb54..48ce5659 100644 --- a/evrApp/src/devEvrEvent.cpp +++ b/evrApp/src/devEvrEvent.cpp @@ -153,12 +153,10 @@ try { post_event(prec->val); if(prec->tse==epicsTimeEventDeviceTime){ - epicsTimeStampUTag ts; - p->evr->getTimeStamp(&ts, p->event); - prec->time.secPastEpoch = ts.secPastEpoch; - prec->time.nsec = ts.nsec; #ifdef DBR_UTAG - prec->utag = static_cast(ts.utag); + p->evr->getTimeStamp(&prec->time,p->event,prec->utag); +#else + p->evr->getTimeStamp(&prec->time,p->event); #endif } @@ -203,12 +201,10 @@ try { #endif if(prec->tse==epicsTimeEventDeviceTime){ - epicsTimeStampUTag ts; - p->evr->getTimeStamp(&ts, p->event); - prec->time.secPastEpoch = ts.secPastEpoch; - prec->time.nsec = ts.nsec; #ifdef DBR_UTAG - prec->utag = static_cast(ts.utag); + p->evr->getTimeStamp(&prec->time,p->event,prec->utag); +#else + p->evr->getTimeStamp(&prec->time,p->event); #endif } return 0; @@ -228,12 +224,10 @@ static long process_event(eventRecord *prec) long ret=0; try { if(prec->tse==epicsTimeEventDeviceTime){ - epicsTimeStampUTag ts; - p->evr->getTimeStamp(&ts, p->event); - prec->time.secPastEpoch = ts.secPastEpoch; - prec->time.nsec = ts.nsec; #ifdef DBR_UTAG - prec->utag = static_cast(ts.utag); + p->evr->getTimeStamp(&prec->time,p->event,prec->utag); +#else + p->evr->getTimeStamp(&prec->time,p->event); #endif } diff --git a/evrApp/src/evr/evr.h b/evrApp/src/evr/evr.h index 9a46fb6c..08ca9361 100644 --- a/evrApp/src/evr/evr.h +++ b/evrApp/src/evr/evr.h @@ -38,12 +38,6 @@ enum TSSource { typedef epicsUInt32 epicsUTag; #endif -struct epicsTimeStampUTag { - epicsUInt32 secPastEpoch; /**< \brief seconds since 0000 Jan 1, 1990 */ - epicsUInt32 nsec; /**< \brief nanoseconds within second */ - epicsUTag utag; /**< \brief user defined tag */ -}; - /**@brief Base interface for EVRs. * * This is the interface which the generic EVR device support @@ -157,7 +151,7 @@ class epicsShareClass EVR : public mrf::ObjectInst *@return false When ts could not be updated */ virtual bool getTimeStamp(epicsTimeStamp *ts,epicsUInt32 event)=0; - virtual bool getTimeStamp(epicsTimeStampUTag *ts,epicsUInt32 event) {return 0;}; + virtual bool getTimeStamp(epicsTimeStamp *ts,epicsUInt32 event, epicsUTag &utag) {return 0;}; /** Returns the current value of the Timestamp Event Counter *@param tks Pointer to be filled with the counter value diff --git a/evrMrmApp/src/drvem.cpp b/evrMrmApp/src/drvem.cpp index b79fdcee..c7decad8 100644 --- a/evrMrmApp/src/drvem.cpp +++ b/evrMrmApp/src/drvem.cpp @@ -834,10 +834,10 @@ EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event) } bool -EVRMRM::getTimeStamp(epicsTimeStampUTag *ret,epicsUInt32 event) +EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event, epicsUTag &utag) { if(!ret) throw std::runtime_error("Invalid argument"); - epicsTimeStampUTag tstag; + epicsTimeStamp ts; SCOPED_LOCK(evrLock); if(timestampValidlast_sec; - tstag.nsec=entry->last_evt; - tstag.utag=entry->utag; + ts.secPastEpoch=entry->last_sec; + ts.nsec=entry->last_evt; + utag=entry->utag; } else { @@ -868,9 +868,9 @@ EVRMRM::getTimeStamp(epicsTimeStampUTag *ret,epicsUInt32 event) // Latch timestamp WRITE32(base, Control, ctrl|Control_tsltch); - tstag.secPastEpoch=READ32(base, TSSecLatch); - tstag.nsec=READ32(base, TSEvtLatch); - tstag.utag = 0; + ts.secPastEpoch=READ32(base, TSSecLatch); + ts.nsec=READ32(base, TSEvtLatch); + utag = 0; /* BUG: There was a firmware bug which occasionally * causes the previous write to fail with a VME bus @@ -887,10 +887,10 @@ EVRMRM::getTimeStamp(epicsTimeStampUTag *ret,epicsUInt32 event) } - if(!convertTS(&tstag)) + if(!convertTS(&ts)) return false; - *ret = tstag; + *ret = ts; return true; } @@ -1647,4 +1647,3 @@ EVRMRM::eventUtagSet(const epicsUInt32 event, epicsUTag tag) { events[event].utag = tag; return; } - diff --git a/evrMrmApp/src/drvem.h b/evrMrmApp/src/drvem.h index 25e7369a..601d6eb7 100644 --- a/evrMrmApp/src/drvem.h +++ b/evrMrmApp/src/drvem.h @@ -178,7 +178,7 @@ class epicsShareClass EVRMRM : public mrf::ObjectInst, virtual IOSCANPVT TimeStampValidEvent() const OVERRIDE FINAL {return timestampValidChange;} virtual bool getTimeStamp(epicsTimeStamp *ts,epicsUInt32 event) OVERRIDE FINAL; - virtual bool getTimeStamp(epicsTimeStampUTag *ts,epicsUInt32 event) OVERRIDE FINAL; + virtual bool getTimeStamp(epicsTimeStamp *ts, epicsUInt32 event, epicsUTag &utag) OVERRIDE FINAL; virtual bool getTicks(epicsUInt32 *tks) OVERRIDE FINAL; virtual IOSCANPVT eventOccurred(epicsUInt32 event) const OVERRIDE FINAL; virtual void eventNotifyAdd(epicsUInt32, eventCallback, void*) OVERRIDE FINAL; From 95b1e3f90b0e789f1a2fe35bed27fa19487e684b Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Thu, 30 Nov 2023 15:27:28 +0100 Subject: [PATCH 04/23] fix: convertTS does not need the template anymore. --- evrMrmApp/src/drvem.cpp | 8 ++++---- evrMrmApp/src/drvem.h | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/evrMrmApp/src/drvem.cpp b/evrMrmApp/src/drvem.cpp index c7decad8..4e16fd9f 100644 --- a/evrMrmApp/src/drvem.cpp +++ b/evrMrmApp/src/drvem.cpp @@ -826,7 +826,7 @@ EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event) } - if(!convertTS(&ts)) + if(!convertTS(&ts)) return false; *ret = ts; @@ -898,8 +898,8 @@ EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event, epicsUTag &utag) /** @brief In place conversion between raw posix sec+ticks to EPICS sec+nsec. @returns false if conversion failed */ -template -bool EVRMRM::convertTS(TimeStampT* ts) + +bool EVRMRM::convertTS(epicsTimeStamp* ts) { // First validate the input @@ -1423,7 +1423,7 @@ EVRMRM::drain_fifo() active.flushtime.secPastEpoch = evt.last_sec; active.flushtime.nsec = evt.last_evt; - active.ok &= convertTS(&active.flushtime); + active.ok &= convertTS(&active.flushtime); tbuf->doFlush(); } diff --git a/evrMrmApp/src/drvem.h b/evrMrmApp/src/drvem.h index 601d6eb7..cdbef34e 100644 --- a/evrMrmApp/src/drvem.h +++ b/evrMrmApp/src/drvem.h @@ -184,8 +184,7 @@ class epicsShareClass EVRMRM : public mrf::ObjectInst, virtual void eventNotifyAdd(epicsUInt32, eventCallback, void*) OVERRIDE FINAL; virtual void eventNotifyDel(epicsUInt32, eventCallback, void*) OVERRIDE FINAL; - template - bool convertTS(TimeStampT* ts); + bool convertTS(epicsTimeStamp* ts); virtual epicsUInt16 dbus() const OVERRIDE FINAL; From 014b94d11d70b901bdcadfb2d498f56cafa539b1 Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Thu, 30 Nov 2023 15:53:39 +0100 Subject: [PATCH 05/23] fix: Minimal adjustment to follow the master branch. --- evrApp/Db/evrevent.db | 2 +- evrApp/src/devEvrEvent.cpp | 1 + evrMrmApp/src/drvem.cpp | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/evrApp/Db/evrevent.db b/evrApp/Db/evrevent.db index a54908f1..ab1f1414 100644 --- a/evrApp/Db/evrevent.db +++ b/evrApp/Db/evrevent.db @@ -34,7 +34,7 @@ record(calc, "$(EN)Cnt-I") { # EN = record name prefix # OBJ = EVR devObj name # CODE = Event code (hardware) -record(int64out, "$(EN)-UTag-SP") { +record(int64out, "$(EN)UTag-SP") { field(DTYP, "UTAG Source") field(OUT , "@OBJ=$(OBJ),Code=$(CODE)") field(VAL , "0") diff --git a/evrApp/src/devEvrEvent.cpp b/evrApp/src/devEvrEvent.cpp index 48ce5659..0f68bd6f 100644 --- a/evrApp/src/devEvrEvent.cpp +++ b/evrApp/src/devEvrEvent.cpp @@ -207,6 +207,7 @@ try { p->evr->getTimeStamp(&prec->time,p->event); #endif } + return 0; } catch(std::runtime_error& e) { recGblRecordError(S_dev_noDevice, (void*)prec, e.what()); diff --git a/evrMrmApp/src/drvem.cpp b/evrMrmApp/src/drvem.cpp index 4e16fd9f..82a193c8 100644 --- a/evrMrmApp/src/drvem.cpp +++ b/evrMrmApp/src/drvem.cpp @@ -898,8 +898,8 @@ EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event, epicsUTag &utag) /** @brief In place conversion between raw posix sec+ticks to EPICS sec+nsec. @returns false if conversion failed */ - -bool EVRMRM::convertTS(epicsTimeStamp* ts) +bool +EVRMRM::convertTS(epicsTimeStamp* ts) { // First validate the input From 1e3c12508e267eb4964dfaa07b00245d0eab0340 Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Thu, 30 Nov 2023 16:23:08 +0100 Subject: [PATCH 06/23] fix: UTag value is arbitrary based, not for s&r. --- evrApp/Db/evrevent.db | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evrApp/Db/evrevent.db b/evrApp/Db/evrevent.db index ab1f1414..a33fe2f7 100644 --- a/evrApp/Db/evrevent.db +++ b/evrApp/Db/evrevent.db @@ -38,5 +38,5 @@ record(int64out, "$(EN)UTag-SP") { field(DTYP, "UTAG Source") field(OUT , "@OBJ=$(OBJ),Code=$(CODE)") field(VAL , "0") - info(autosaveFields_pass0, "OUT VAL") + info(autosaveFields_pass0, "OUT") } From b5888dbfdf29350409a8a7428b685bec649a5b61 Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Fri, 1 Dec 2023 12:25:59 +0100 Subject: [PATCH 07/23] perf: getTimeStamp optimized to basically one function. --- evrMrmApp/src/drvem.cpp | 66 +++++------------------------------------ 1 file changed, 7 insertions(+), 59 deletions(-) diff --git a/evrMrmApp/src/drvem.cpp b/evrMrmApp/src/drvem.cpp index 82a193c8..38e250e9 100644 --- a/evrMrmApp/src/drvem.cpp +++ b/evrMrmApp/src/drvem.cpp @@ -775,7 +775,7 @@ EVRMRM::TimeStampValid() const } bool -EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event) +EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event, epicsUTag &utag) { if(!ret) throw std::runtime_error("Invalid argument"); epicsTimeStamp ts; @@ -798,6 +798,7 @@ EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event) ts.secPastEpoch=entry->last_sec; ts.nsec=entry->last_evt; + utag=entry->utag; } else { @@ -810,6 +811,7 @@ EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event) ts.secPastEpoch=READ32(base, TSSecLatch); ts.nsec=READ32(base, TSEvtLatch); + utag=0; /* BUG: There was a firmware bug which occasionally * causes the previous write to fail with a VME bus @@ -833,68 +835,14 @@ EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event) return true; } +// The backward compatibility wrapper for the epics-base without UTAG support. bool -EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event, epicsUTag &utag) +EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event) { - if(!ret) throw std::runtime_error("Invalid argument"); - epicsTimeStamp ts; - - SCOPED_LOCK(evrLock); - if(timestampValid0 && event<=255) { - // Get time of last event code # - - eventCode *entry=&events[event]; - - // Fail if event is not mapped - if (!entry->interested || - ( entry->last_sec==0 && - entry->last_evt==0) ) - { - return false; - } - - ts.secPastEpoch=entry->last_sec; - ts.nsec=entry->last_evt; - utag=entry->utag; - - - } else { - // Get current absolute time - - epicsUInt32 ctrl=READ32(base, Control); - - // Latch timestamp - WRITE32(base, Control, ctrl|Control_tsltch); - - ts.secPastEpoch=READ32(base, TSSecLatch); - ts.nsec=READ32(base, TSEvtLatch); - utag = 0; - - /* BUG: There was a firmware bug which occasionally - * causes the previous write to fail with a VME bus - * error, and 0 the Control register. - * - * This issues has been fixed in VME firmwares EVRv 5 - * pre2 and EVG v3 pre2. Feb 2011 - */ - epicsUInt32 ctrl2=READ32(base, Control); - if (ctrl2!=ctrl) { // tsltch bit is write-only - printf("Get timestamp: control register write fault. Written: %08x, readback: %08x\n",ctrl,ctrl2); - WRITE32(base, Control, ctrl); - } - - } - - if(!convertTS(&ts)) - return false; - - *ret = ts; - return true; + epicsUTag fake_utag = 0; + return EVRMRM::getTimeStamp(ret, event, fake_utag); } - /** @brief In place conversion between raw posix sec+ticks to EPICS sec+nsec. @returns false if conversion failed */ From 388f055661144d10bd5a7f6ab70d94b8bc967003 Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Fri, 1 Dec 2023 12:41:46 +0100 Subject: [PATCH 08/23] docs: File header adjusted accordingly. --- evrApp/src/devEvrUtag.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/evrApp/src/devEvrUtag.cpp b/evrApp/src/devEvrUtag.cpp index 50ad5a8f..6c2d65c5 100644 --- a/evrApp/src/devEvrUtag.cpp +++ b/evrApp/src/devEvrUtag.cpp @@ -1,7 +1,4 @@ /*************************************************************************\ -* Copyright (c) 2010 Brookhaven Science Associates, as Operator of -* Brookhaven National Laboratory. -* Copyright (c) 2015 Paul Scherrer Institute (PSI), Villigen, Switzerland * Copyright (c) 2023 European Spallation Source ERIC (ESS), Lund, Sweden * mrfioc2 is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. From 6568af5c716a56b59265b1d9a2123ce6c99b7bdd Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Fri, 1 Dec 2023 13:33:43 +0100 Subject: [PATCH 09/23] fix: epicsUTag always 64 bit. --- evrApp/src/evr/evr.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/evrApp/src/evr/evr.h b/evrApp/src/evr/evr.h index 08ca9361..338d28c6 100644 --- a/evrApp/src/evr/evr.h +++ b/evrApp/src/evr/evr.h @@ -34,8 +34,9 @@ enum TSSource { TSSourceDBus4=2 }; +// Backward compatibility if UTAG is not supported by the epics-base. #ifndef DBR_UTAG - typedef epicsUInt32 epicsUTag; + typedef epicsUInt64 epicsUTag; #endif /**@brief Base interface for EVRs. From 86efe4d98b9984e03d62d9cfca1c7acc3ba74933 Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Mon, 4 Dec 2023 12:51:21 +0100 Subject: [PATCH 10/23] test: UTag tests. --- evrApp/Db/evrevent.db | 12 ++++++------ evrApp/src/devEvrEvent.cpp | 13 +++++++++---- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/evrApp/Db/evrevent.db b/evrApp/Db/evrevent.db index a33fe2f7..d4cf5d73 100644 --- a/evrApp/Db/evrevent.db +++ b/evrApp/Db/evrevent.db @@ -34,9 +34,9 @@ record(calc, "$(EN)Cnt-I") { # EN = record name prefix # OBJ = EVR devObj name # CODE = Event code (hardware) -record(int64out, "$(EN)UTag-SP") { - field(DTYP, "UTAG Source") - field(OUT , "@OBJ=$(OBJ),Code=$(CODE)") - field(VAL , "0") - info(autosaveFields_pass0, "OUT") -} +# record(int64out, "$(EN)UTag-SP") { +# field(DTYP, "UTAG Source") +# field(OUT , "@OBJ=$(OBJ),Code=$(CODE)") +# field(VAL , "0") +# info(autosaveFields_pass0, "OUT") +# } diff --git a/evrApp/src/devEvrEvent.cpp b/evrApp/src/devEvrEvent.cpp index 0f68bd6f..8238565d 100644 --- a/evrApp/src/devEvrEvent.cpp +++ b/evrApp/src/devEvrEvent.cpp @@ -43,6 +43,7 @@ struct priv { EVR* evr; char obj[30]; int event; + epicsUTag utag; #ifdef USE_EVENT_NAMES EVENTPVT handle; char prev[sizeof( ((stringoutRecord*)0)->val)]; @@ -149,14 +150,18 @@ static long process_longout(longoutRecord *prec) long ret=0; try { - if (prec->val>=0 && prec->val<=255) - post_event(prec->val); + if (p->event>=0 && p->event<=255) + post_event(p->event); if(prec->tse==epicsTimeEventDeviceTime){ #ifdef DBR_UTAG - p->evr->getTimeStamp(&prec->time,p->event,prec->utag); + // Inject the value as the UTAG reference + p->utag = static_cast(prec->val); + p->evr->eventUtagSet(p->event, p->utag); + prec->utag = static_cast(p->utag); + p->evr->getTimeStamp(&prec->time,p->event,prec->utag); #else - p->evr->getTimeStamp(&prec->time,p->event); + p->evr->getTimeStamp(&prec->time,p->event); #endif } From 5848d9a04a6e62cad72c1cddc0c496c5264637e2 Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Mon, 4 Dec 2023 21:55:05 +0100 Subject: [PATCH 11/23] perf: Reduction of UTag operations to devEvrEvent only. --- evrApp/src/devEvrEvent.cpp | 21 +++++++-------------- evrApp/src/devEvrUtag.cpp | 2 +- evrApp/src/evr/evr.h | 4 ++-- evrMrmApp/src/drvem.cpp | 4 ++-- evrMrmApp/src/drvem.h | 4 ++-- 5 files changed, 14 insertions(+), 21 deletions(-) diff --git a/evrApp/src/devEvrEvent.cpp b/evrApp/src/devEvrEvent.cpp index 8238565d..4c48a0a0 100644 --- a/evrApp/src/devEvrEvent.cpp +++ b/evrApp/src/devEvrEvent.cpp @@ -43,7 +43,6 @@ struct priv { EVR* evr; char obj[30]; int event; - epicsUTag utag; #ifdef USE_EVENT_NAMES EVENTPVT handle; char prev[sizeof( ((stringoutRecord*)0)->val)]; @@ -154,14 +153,10 @@ try { post_event(p->event); if(prec->tse==epicsTimeEventDeviceTime){ -#ifdef DBR_UTAG - // Inject the value as the UTAG reference - p->utag = static_cast(prec->val); - p->evr->eventUtagSet(p->event, p->utag); - prec->utag = static_cast(p->utag); - p->evr->getTimeStamp(&prec->time,p->event,prec->utag); -#else p->evr->getTimeStamp(&prec->time,p->event); +#ifdef DBR_UTAG + prec->utag = static_cast(prec->val); + p->evr->setUtag(prec->utag, p->event); #endif } @@ -206,10 +201,9 @@ try { #endif if(prec->tse==epicsTimeEventDeviceTime){ + p->evr->getTimeStamp(&prec->time,p->event); #ifdef DBR_UTAG - p->evr->getTimeStamp(&prec->time,p->event,prec->utag); -#else - p->evr->getTimeStamp(&prec->time,p->event); + prec->utag = p->evr->getUtag(p->event); #endif } @@ -230,10 +224,9 @@ static long process_event(eventRecord *prec) long ret=0; try { if(prec->tse==epicsTimeEventDeviceTime){ + p->evr->getTimeStamp(&prec->time,p->event); #ifdef DBR_UTAG - p->evr->getTimeStamp(&prec->time,p->event,prec->utag); -#else - p->evr->getTimeStamp(&prec->time,p->event); + prec->utag = p->evr->getUtag(p->event); #endif } diff --git a/evrApp/src/devEvrUtag.cpp b/evrApp/src/devEvrUtag.cpp index 6c2d65c5..fec64346 100644 --- a/evrApp/src/devEvrUtag.cpp +++ b/evrApp/src/devEvrUtag.cpp @@ -107,7 +107,7 @@ try { // Inject the value as the UTAG reference p->utag = static_cast(prec->val); - p->evr->eventUtagSet(p->event, p->utag); + p->evr->setUtag(p->utag, p->event); #ifdef DBR_UTAG prec->utag = static_cast(p->utag); #endif diff --git a/evrApp/src/evr/evr.h b/evrApp/src/evr/evr.h index 338d28c6..f3518fdf 100644 --- a/evrApp/src/evr/evr.h +++ b/evrApp/src/evr/evr.h @@ -202,8 +202,8 @@ class epicsShareClass EVR : public mrf::ObjectInst * Get/Set UTAG value for specific event */ /*@{*/ - virtual epicsUTag eventUtag(const epicsUInt32 event) const {return 0;}; - virtual void eventUtagSet(const epicsUInt32 event, epicsUTag tag) {}; + virtual epicsUTag getUtag(const epicsUInt32 event) const {return 0;}; + virtual void setUtag(epicsUTag tag, const epicsUInt32 event) {}; /*@}*/ private: diff --git a/evrMrmApp/src/drvem.cpp b/evrMrmApp/src/drvem.cpp index 38e250e9..4d3d2fc2 100644 --- a/evrMrmApp/src/drvem.cpp +++ b/evrMrmApp/src/drvem.cpp @@ -1576,7 +1576,7 @@ EVRMRM::seconds_tick(void *raw, epicsUInt32) // Get UTAG value for specific event epicsUTag -EVRMRM::eventUtag(const epicsUInt32 event) const { +EVRMRM::getUtag(const epicsUInt32 event) const { if(event==0) return 0; else if(event>255) throw std::runtime_error("Event code out of range"); SCOPED_LOCK(evrLock); @@ -1586,7 +1586,7 @@ EVRMRM::eventUtag(const epicsUInt32 event) const { // Set UTAG value for specific event void -EVRMRM::eventUtagSet(const epicsUInt32 event, epicsUTag tag) { +EVRMRM::setUtag(epicsUTag tag, const epicsUInt32 event) { if(event==0) return; else if(event>255) throw std::runtime_error("Event code out of range"); SCOPED_LOCK(evrLock); diff --git a/evrMrmApp/src/drvem.h b/evrMrmApp/src/drvem.h index cdbef34e..9b39148b 100644 --- a/evrMrmApp/src/drvem.h +++ b/evrMrmApp/src/drvem.h @@ -198,8 +198,8 @@ class epicsShareClass EVRMRM : public mrf::ObjectInst, virtual epicsUInt32 FIFOEvtCount() const OVERRIDE FINAL {return count_fifo_events;} virtual epicsUInt32 FIFOLoopCount() const OVERRIDE FINAL {return count_fifo_loops;} - virtual epicsUTag eventUtag(const epicsUInt32 event) const OVERRIDE FINAL; - virtual void eventUtagSet(const epicsUInt32 event, epicsUTag tag) OVERRIDE FINAL; + virtual epicsUTag getUtag(const epicsUInt32 event) const OVERRIDE FINAL; + virtual void setUtag(epicsUTag tag, const epicsUInt32 event) OVERRIDE FINAL; void enableIRQ(void); From c46c2c2c0136ef0b3bacdbba288a5839d6f378ca Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Mon, 4 Dec 2023 22:37:21 +0100 Subject: [PATCH 12/23] perf: evreventutag.db handling enhanced. --- evrApp/Db/evreventutag.db | 22 ++++ evrApp/src/devEvrEventUtag.cpp | 193 +++++++++++++++++++++++++++++++++ evrApp/src/evrSupportBase7.dbd | 3 +- 3 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 evrApp/Db/evreventutag.db create mode 100644 evrApp/src/devEvrEventUtag.cpp diff --git a/evrApp/Db/evreventutag.db b/evrApp/Db/evreventutag.db new file mode 100644 index 00000000..32ab1a16 --- /dev/null +++ b/evrApp/Db/evreventutag.db @@ -0,0 +1,22 @@ + +# Macros: +# EN = record name prefix +# OBJ = EVR devObj name +# CODE = Event code (hardware) + +record(int64out, "$(EN)-SP") { + field(DTYP, "EVR Event Utag") + field(SCAN, "I/O Intr") + field(OUT , "@OBJ=$(OBJ),Code=$(CODE)") + field(TSE , "-2") # from device support + field(FLNK, "$(EN)Cnt-I") + info(autosaveFields_pass0, "OUT") +} + +record(calc, "$(EN)Cnt-I") { + field(SDIS, "$(EN)-SP") + field(DISV, "0") + field(CALC, "A+1") + field(INPA, "$(EN)Cnt-I NPP") + field(TSEL, "$(EN)-SP.TIME") +} diff --git a/evrApp/src/devEvrEventUtag.cpp b/evrApp/src/devEvrEventUtag.cpp new file mode 100644 index 00000000..d3e97f82 --- /dev/null +++ b/evrApp/src/devEvrEventUtag.cpp @@ -0,0 +1,193 @@ +#include +#include +#include +#include +#include +#include +#include // For S_dev_* +#include +#include + +#include +#include + +#include "devObj.h" +#include "evr/evr.h" + +#include "linkoptions.h" + +#include +#include + +#if defined(EPICS_VERSION_INT) && EPICS_VERSION_INT >= VERSION_INT(3, 15, 1, 0) +// Use new API allowing events to have name strings instead of just numbers +#define USE_EVENT_NAMES +#endif + +/***************** Event *****************/ + +struct priv +{ + EVR *evr; + char obj[30]; + int event; +}; + +static const linkOptionDef eventdef[] = + { + linkString(priv, obj, "OBJ", 1, 0), + linkInt32(priv, event, "Code", 1, 0), + linkOptionEnd}; + +static long add_record(struct dbCommon *prec, struct link *link) +{ + long ret = 0; + try + { + assert(link->type == INST_IO); + + mrf::auto_ptr p(new priv); + p->event = 0; + + if (linkOptionsStore(eventdef, p.get(), link->value.instio.string, 0)) + throw std::runtime_error("Couldn't parse link string"); + + mrf::Object *O = mrf::Object::getObject(p->obj); + if (!O) + { + errlogPrintf("%s: failed to find object '%s'\n", prec->name, p->obj); + return S_db_errArg; + } + p->evr = dynamic_cast(O); + if (!p->evr) + throw std::runtime_error("Failed to lookup device"); + + if (!p->evr->interestedInEvent(p->event, true)) + throw std::runtime_error("Failed to register interest"); + + prec->dpvt = (void *)p.release(); + + return 0; + } + catch (std::runtime_error &e) + { + recGblRecordError(S_dev_noDevice, (void *)prec, e.what()); + ret = S_dev_noDevice; + } + catch (std::exception &e) + { + recGblRecordError(S_db_noMemory, (void *)prec, e.what()); + ret = S_db_noMemory; + } + return ret; +} + +static long del_record(struct dbCommon *prec) +{ + priv *p = static_cast(prec->dpvt); + long ret = 0; + if (!p) + return 0; + try + { + + p->evr->interestedInEvent(p->event, false); + delete p; + prec->dpvt = 0; + } + catch (std::runtime_error &e) + { + recGblRecordError(S_dev_noDevice, (void *)prec, e.what()); + ret = S_dev_noDevice; + } + catch (std::exception &e) + { + recGblRecordError(S_db_noMemory, (void *)prec, e.what()); + ret = S_db_noMemory; + } + return ret; +} + +static long +get_ioint_info(int, dbCommon *prec, IOSCANPVT *io) +{ + if (!prec->dpvt) + return S_db_errArg; + priv *p = static_cast(prec->dpvt); + long ret = 0; + try + { + + if (!p) + return 1; + + *io = p->evr->eventOccurred(p->event); + + return 0; + } + catch (std::runtime_error &e) + { + recGblRecordError(S_dev_noDevice, (void *)prec, e.what()); + ret = S_dev_noDevice; + } + catch (std::exception &e) + { + recGblRecordError(S_db_noMemory, (void *)prec, e.what()); + ret = S_db_noMemory; + } + *io = NULL; + return ret; +} + +static long process_int64out(int64outRecord *prec) +{ + priv *p = static_cast(prec->dpvt); + long ret = 0; + try + { + + if (p->event >= 0 && p->event <= 255) + post_event(p->event); + + if (prec->tse == epicsTimeEventDeviceTime) + { + p->evr->getTimeStamp(&prec->time, p->event); +#ifdef DBR_UTAG + prec->utag = static_cast(prec->val); + p->evr->setUtag(prec->utag, p->event); +#endif + } + + return 0; + } + catch (std::runtime_error &e) + { + recGblRecordError(S_dev_noDevice, (void *)prec, e.what()); + ret = S_dev_noDevice; + } + catch (std::exception &e) + { + recGblRecordError(S_db_noMemory, (void *)prec, e.what()); + ret = S_db_noMemory; + } + return ret; +} + +static long add_int64out(struct dbCommon *precord) +{ + return add_record(precord, &((struct int64outRecord *)precord)->out); +} + +dsxt dxtI64OEventUtagEVR = {add_int64out, del_record}; +static common_dset devI64OEventUtagEVR = { + 6, NULL, + dset_cast(&init_dset<&dxtI64OEventUtagEVR>), + (DEVSUPFUN)init_record_empty, + (DEVSUPFUN)&get_ioint_info, + dset_cast(&process_int64out), + NULL}; + +extern "C" +{ + epicsExportAddress(dset, devI64OEventUtagEVR); +} diff --git a/evrApp/src/evrSupportBase7.dbd b/evrApp/src/evrSupportBase7.dbd index fd96d74d..a9249622 100644 --- a/evrApp/src/evrSupportBase7.dbd +++ b/evrApp/src/evrSupportBase7.dbd @@ -1,2 +1,3 @@ # '@C=..., Code=hweventnum' -device(int64out, INST_IO, devINT64UTAGEVR, "UTAG Source") +# device(int64out, INST_IO, devINT64UTAGEVR, "UTAG Source") +device(int64out, INST_IO, devI64OEventUtagEVR, "EVR Event Utag") From 56f8bc29ef6dc211dcd8303edd6bf1745268a455 Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Tue, 5 Dec 2023 10:52:13 +0100 Subject: [PATCH 13/23] fix: event added to the EvrEventUtag handling. --- evrApp/Db/evrevent.db | 14 ---- evrApp/Db/evreventutag.db | 5 +- evrApp/src/Makefile | 2 +- evrApp/src/devEvrEvent.cpp | 1 + evrApp/src/devEvrEventUtag.cpp | 49 ++++++++++- evrApp/src/devEvrUtag.cpp | 146 --------------------------------- evrApp/src/evrSupportBase7.dbd | 1 + 7 files changed, 54 insertions(+), 164 deletions(-) delete mode 100644 evrApp/src/devEvrUtag.cpp diff --git a/evrApp/Db/evrevent.db b/evrApp/Db/evrevent.db index d4cf5d73..a3093879 100644 --- a/evrApp/Db/evrevent.db +++ b/evrApp/Db/evrevent.db @@ -26,17 +26,3 @@ record(calc, "$(EN)Cnt-I") { field(INPA, "$(EN)Cnt-I NPP") field(TSEL, "$(EN)-SP.TIME") } - - -# Mapping between hardware event code and a software database event -# -# Macros: -# EN = record name prefix -# OBJ = EVR devObj name -# CODE = Event code (hardware) -# record(int64out, "$(EN)UTag-SP") { -# field(DTYP, "UTAG Source") -# field(OUT , "@OBJ=$(OBJ),Code=$(CODE)") -# field(VAL , "0") -# info(autosaveFields_pass0, "OUT") -# } diff --git a/evrApp/Db/evreventutag.db b/evrApp/Db/evreventutag.db index 32ab1a16..7d9199d4 100644 --- a/evrApp/Db/evreventutag.db +++ b/evrApp/Db/evreventutag.db @@ -14,8 +14,9 @@ record(int64out, "$(EN)-SP") { } record(calc, "$(EN)Cnt-I") { - field(SDIS, "$(EN)-SP") - field(DISV, "0") + field(DESC, "TS and UTAG source") + #field(SDIS, "$(EN)-SP") + #field(DISV, "0") field(CALC, "A+1") field(INPA, "$(EN)Cnt-I NPP") field(TSEL, "$(EN)-SP.TIME") diff --git a/evrApp/src/Makefile b/evrApp/src/Makefile index 0da9798e..a337cc96 100644 --- a/evrApp/src/Makefile +++ b/evrApp/src/Makefile @@ -29,7 +29,7 @@ evr_SRCS += evrGTIF.cpp evr_SRCS += devEvrStringIO.cpp ifdef BASE_7_0 -evr_SRCS += devEvrUtag.cpp +evr_SRCS += devEvrEventUtag.cpp endif evr_SRCS += devEvrEvent.cpp diff --git a/evrApp/src/devEvrEvent.cpp b/evrApp/src/devEvrEvent.cpp index 4c48a0a0..cf5364b2 100644 --- a/evrApp/src/devEvrEvent.cpp +++ b/evrApp/src/devEvrEvent.cpp @@ -157,6 +157,7 @@ try { #ifdef DBR_UTAG prec->utag = static_cast(prec->val); p->evr->setUtag(prec->utag, p->event); + std::cout << "evrevent.cpp " << " p->event " << p->event << " prec->val " << prec->val << " prec->utag " << prec->utag << std::endl; #endif } diff --git a/evrApp/src/devEvrEventUtag.cpp b/evrApp/src/devEvrEventUtag.cpp index d3e97f82..753f6be5 100644 --- a/evrApp/src/devEvrEventUtag.cpp +++ b/evrApp/src/devEvrEventUtag.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include "devObj.h" @@ -152,9 +153,40 @@ static long process_int64out(int64outRecord *prec) if (prec->tse == epicsTimeEventDeviceTime) { p->evr->getTimeStamp(&prec->time, p->event); -#ifdef DBR_UTAG + // #ifdef DBR_UTAG prec->utag = static_cast(prec->val); p->evr->setUtag(prec->utag, p->event); + std::cout << "devEvrEventUtag.cpp " + << " p->event " << p->event << " prec->val " << prec->val << " prec->utag " << prec->utag << std::endl; + // #endif + } + + return 0; + } + catch (std::runtime_error &e) + { + recGblRecordError(S_dev_noDevice, (void *)prec, e.what()); + ret = S_dev_noDevice; + } + catch (std::exception &e) + { + recGblRecordError(S_db_noMemory, (void *)prec, e.what()); + ret = S_db_noMemory; + } + return ret; +} + +static long process_event(eventRecord *prec) +{ + priv *p = static_cast(prec->dpvt); + long ret = 0; + try + { + if (prec->tse == epicsTimeEventDeviceTime) + { + p->evr->getTimeStamp(&prec->time, p->event); +#ifdef DBR_UTAG + prec->utag = p->evr->getUtag(p->event); #endif } @@ -178,6 +210,11 @@ static long add_int64out(struct dbCommon *precord) return add_record(precord, &((struct int64outRecord *)precord)->out); } +static long add_event(struct dbCommon *precord) +{ + return add_record(precord, &((struct eventRecord *)precord)->inp); +} + dsxt dxtI64OEventUtagEVR = {add_int64out, del_record}; static common_dset devI64OEventUtagEVR = { 6, NULL, @@ -187,7 +224,17 @@ static common_dset devI64OEventUtagEVR = { dset_cast(&process_int64out), NULL}; +dsxt dxtEVEventUtagEVR = {add_event, del_record}; +static common_dset devEVEventUtagEVR = { + 6, NULL, + dset_cast(&init_dset<&dxtEVEventUtagEVR>), + (DEVSUPFUN)init_record_empty, + (DEVSUPFUN)&get_ioint_info, + dset_cast(&process_event), + NULL}; + extern "C" { epicsExportAddress(dset, devI64OEventUtagEVR); + epicsExportAddress(dset, devEVEventUtagEVR); } diff --git a/evrApp/src/devEvrUtag.cpp b/evrApp/src/devEvrUtag.cpp deleted file mode 100644 index fec64346..00000000 --- a/evrApp/src/devEvrUtag.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2023 European Spallation Source ERIC (ESS), Lund, Sweden -* mrfioc2 is distributed subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* - * Author: Joao Paulo Martins - */ - -#include -#include -#include -#include -#include -#include -#include // For S_dev_* -#include -#include - -#include -#include - -#include "devObj.h" -#include "evr/evr.h" - -#include "linkoptions.h" - -#include -#include - -struct priv { - EVR* evr; - char obj[30]; - int event; - epicsUTag utag; -}; - -static const -linkOptionDef utagdef[] = -{ - linkString (priv, obj , "OBJ" , 1, 0), - linkInt32 (priv, event, "Code", 1, 0), - linkOptionEnd -}; - -static -long add_record(struct dbCommon *prec, struct link* link) -{ - long ret=0; -try { - assert(link->type==INST_IO); - - mrf::auto_ptr p(new priv); - p->utag=0; - p->event=0; - - if (linkOptionsStore(utagdef, p.get(), link->value.instio.string, 0)) - throw std::runtime_error("Couldn't parse link string"); - - mrf::Object *O=mrf::Object::getObject(p->obj); - if(!O) { - errlogPrintf("%s: failed to find object '%s'\n", prec->name, p->obj); - return S_db_errArg; - } - p->evr=dynamic_cast(O); - if(!p->evr) - throw std::runtime_error("Failed to lookup device"); - - prec->dpvt=(void*)p.release(); - - return 0; -} catch(std::runtime_error& e) { - recGblRecordError(S_dev_noDevice, (void*)prec, e.what()); - ret=S_dev_noDevice; -} catch(std::exception& e) { - recGblRecordError(S_db_noMemory, (void*)prec, e.what()); - ret=S_db_noMemory; -} - return ret; -} - -static -long del_record(struct dbCommon *prec) -{ - priv *p=static_cast(prec->dpvt); - long ret=0; - if (!p) return 0; -try { - - prec->dpvt=0; - -} catch(std::runtime_error& e) { - recGblRecordError(S_dev_noDevice, (void*)prec, e.what()); - ret=S_dev_noDevice; -} catch(std::exception& e) { - recGblRecordError(S_db_noMemory, (void*)prec, e.what()); - ret=S_db_noMemory; -} - return ret; -} - -static long process_int64out(int64outRecord *prec) -{ - priv *p=static_cast(prec->dpvt); - long ret=0; -try { - - // Inject the value as the UTAG reference - p->utag = static_cast(prec->val); - p->evr->setUtag(p->utag, p->event); -#ifdef DBR_UTAG - prec->utag = static_cast(p->utag); -#endif - - return 0; -} catch(std::runtime_error& e) { - recGblRecordError(S_dev_noDevice, (void*)prec, e.what()); - ret=S_dev_noDevice; -} catch(std::exception& e) { - recGblRecordError(S_db_noMemory, (void*)prec, e.what()); - ret=S_db_noMemory; -} - return ret; -} - - -static -long add_int64out(struct dbCommon *precord) -{ - return add_record(precord, &((struct int64outRecord*)precord)->out); -} - -dsxt dxtINT64UTAGEVR={add_int64out,del_record}; -static common_dset devINT64UTAGEVR = { - 6, NULL, - dset_cast(&init_dset<&dxtINT64UTAGEVR>), - (DEVSUPFUN) init_record_empty, - (DEVSUPFUN) NULL, - dset_cast(&process_int64out), - NULL }; - -extern "C" { - -epicsExportAddress(dset,devINT64UTAGEVR); - -} diff --git a/evrApp/src/evrSupportBase7.dbd b/evrApp/src/evrSupportBase7.dbd index a9249622..218a7991 100644 --- a/evrApp/src/evrSupportBase7.dbd +++ b/evrApp/src/evrSupportBase7.dbd @@ -1,3 +1,4 @@ # '@C=..., Code=hweventnum' # device(int64out, INST_IO, devINT64UTAGEVR, "UTAG Source") device(int64out, INST_IO, devI64OEventUtagEVR, "EVR Event Utag") +device(event, INST_IO, devEVEventUtagEVR, "EVR Event Utag") From 6991a38111b4aee1950d2f1d83defa16a8146d56 Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Tue, 5 Dec 2023 14:49:24 +0100 Subject: [PATCH 14/23] refactor: devEvrEvent.cpp applied to the original form. --- evrApp/src/devEvrEvent.cpp | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/evrApp/src/devEvrEvent.cpp b/evrApp/src/devEvrEvent.cpp index cf5364b2..32b2629e 100644 --- a/evrApp/src/devEvrEvent.cpp +++ b/evrApp/src/devEvrEvent.cpp @@ -149,16 +149,11 @@ static long process_longout(longoutRecord *prec) long ret=0; try { - if (p->event>=0 && p->event<=255) - post_event(p->event); + if (prec->val>=0 && prec->val<=255) + post_event(prec->val); if(prec->tse==epicsTimeEventDeviceTime){ - p->evr->getTimeStamp(&prec->time,p->event); -#ifdef DBR_UTAG - prec->utag = static_cast(prec->val); - p->evr->setUtag(prec->utag, p->event); - std::cout << "evrevent.cpp " << " p->event " << p->event << " prec->val " << prec->val << " prec->utag " << prec->utag << std::endl; -#endif + p->evr->getTimeStamp(&prec->time,p->event); } return 0; @@ -202,10 +197,7 @@ try { #endif if(prec->tse==epicsTimeEventDeviceTime){ - p->evr->getTimeStamp(&prec->time,p->event); -#ifdef DBR_UTAG - prec->utag = p->evr->getUtag(p->event); -#endif + p->evr->getTimeStamp(&prec->time,p->event); } return 0; @@ -225,10 +217,7 @@ static long process_event(eventRecord *prec) long ret=0; try { if(prec->tse==epicsTimeEventDeviceTime){ - p->evr->getTimeStamp(&prec->time,p->event); -#ifdef DBR_UTAG - prec->utag = p->evr->getUtag(p->event); -#endif + p->evr->getTimeStamp(&prec->time,p->event); } return 0; From 63c8be41a1712b57070989a9040e136665554344 Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Tue, 5 Dec 2023 14:54:08 +0100 Subject: [PATCH 15/23] refactor: drvem.cpp recovered to its original form. --- evrApp/src/evr/evr.h | 1 - evrFRIBApp/src/evr_frib.h | 6 +++--- evrMrmApp/src/drvem.cpp | 12 +----------- evrMrmApp/src/drvem.h | 1 - 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/evrApp/src/evr/evr.h b/evrApp/src/evr/evr.h index f3518fdf..95588258 100644 --- a/evrApp/src/evr/evr.h +++ b/evrApp/src/evr/evr.h @@ -152,7 +152,6 @@ class epicsShareClass EVR : public mrf::ObjectInst *@return false When ts could not be updated */ virtual bool getTimeStamp(epicsTimeStamp *ts,epicsUInt32 event)=0; - virtual bool getTimeStamp(epicsTimeStamp *ts,epicsUInt32 event, epicsUTag &utag) {return 0;}; /** Returns the current value of the Timestamp Event Counter *@param tks Pointer to be filled with the counter value diff --git a/evrFRIBApp/src/evr_frib.h b/evrFRIBApp/src/evr_frib.h index cc34c36d..bae87a70 100644 --- a/evrFRIBApp/src/evr_frib.h +++ b/evrFRIBApp/src/evr_frib.h @@ -5,8 +5,8 @@ * * Author: Michael Davidsaver */ -#ifndef EVR_FRIB_H -#define EVR_FRIB_H +#ifndef SRC_EVR_FRIB_H +#define SRC_EVR_FRIB_H #include #include @@ -217,4 +217,4 @@ struct EVRFRIB : public mrf::ObjectInst }; -#endif // EVR_FRIB_H +#endif /* SRC_EVR_FRIB_H */ diff --git a/evrMrmApp/src/drvem.cpp b/evrMrmApp/src/drvem.cpp index 4d3d2fc2..755ed93d 100644 --- a/evrMrmApp/src/drvem.cpp +++ b/evrMrmApp/src/drvem.cpp @@ -775,7 +775,7 @@ EVRMRM::TimeStampValid() const } bool -EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event, epicsUTag &utag) +EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event) { if(!ret) throw std::runtime_error("Invalid argument"); epicsTimeStamp ts; @@ -798,7 +798,6 @@ EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event, epicsUTag &utag) ts.secPastEpoch=entry->last_sec; ts.nsec=entry->last_evt; - utag=entry->utag; } else { @@ -811,7 +810,6 @@ EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event, epicsUTag &utag) ts.secPastEpoch=READ32(base, TSSecLatch); ts.nsec=READ32(base, TSEvtLatch); - utag=0; /* BUG: There was a firmware bug which occasionally * causes the previous write to fail with a VME bus @@ -835,14 +833,6 @@ EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event, epicsUTag &utag) return true; } -// The backward compatibility wrapper for the epics-base without UTAG support. -bool -EVRMRM::getTimeStamp(epicsTimeStamp *ret,epicsUInt32 event) -{ - epicsUTag fake_utag = 0; - return EVRMRM::getTimeStamp(ret, event, fake_utag); -} - /** @brief In place conversion between raw posix sec+ticks to EPICS sec+nsec. @returns false if conversion failed */ diff --git a/evrMrmApp/src/drvem.h b/evrMrmApp/src/drvem.h index 9b39148b..c88890ab 100644 --- a/evrMrmApp/src/drvem.h +++ b/evrMrmApp/src/drvem.h @@ -178,7 +178,6 @@ class epicsShareClass EVRMRM : public mrf::ObjectInst, virtual IOSCANPVT TimeStampValidEvent() const OVERRIDE FINAL {return timestampValidChange;} virtual bool getTimeStamp(epicsTimeStamp *ts,epicsUInt32 event) OVERRIDE FINAL; - virtual bool getTimeStamp(epicsTimeStamp *ts, epicsUInt32 event, epicsUTag &utag) OVERRIDE FINAL; virtual bool getTicks(epicsUInt32 *tks) OVERRIDE FINAL; virtual IOSCANPVT eventOccurred(epicsUInt32 event) const OVERRIDE FINAL; virtual void eventNotifyAdd(epicsUInt32, eventCallback, void*) OVERRIDE FINAL; From 82b87cd4a7b70dc730582254ddfc38c26aba0b4c Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Tue, 5 Dec 2023 15:43:38 +0100 Subject: [PATCH 16/23] refactor: EvrEventUtag clean up. --- evrApp/Db/evreventutag.db | 3 +++ evrApp/src/devEvrEventUtag.cpp | 11 ++--------- evrFRIBApp/src/evr_frib.h | 6 +++--- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/evrApp/Db/evreventutag.db b/evrApp/Db/evreventutag.db index 7d9199d4..28612159 100644 --- a/evrApp/Db/evreventutag.db +++ b/evrApp/Db/evreventutag.db @@ -1,3 +1,6 @@ +# Usage of "evreventutag.db" +## Timestaming + UTAG support: import "evreventutag.db" instead of "evrevent.db". +## Timestaming support only: import "evrevent.db" and ignore "evreventutag.db". # Macros: # EN = record name prefix diff --git a/evrApp/src/devEvrEventUtag.cpp b/evrApp/src/devEvrEventUtag.cpp index 753f6be5..0b0459aa 100644 --- a/evrApp/src/devEvrEventUtag.cpp +++ b/evrApp/src/devEvrEventUtag.cpp @@ -20,11 +20,6 @@ #include #include -#if defined(EPICS_VERSION_INT) && EPICS_VERSION_INT >= VERSION_INT(3, 15, 1, 0) -// Use new API allowing events to have name strings instead of just numbers -#define USE_EVENT_NAMES -#endif - /***************** Event *****************/ struct priv @@ -153,12 +148,10 @@ static long process_int64out(int64outRecord *prec) if (prec->tse == epicsTimeEventDeviceTime) { p->evr->getTimeStamp(&prec->time, p->event); - // #ifdef DBR_UTAG +#ifdef DBR_UTAG prec->utag = static_cast(prec->val); p->evr->setUtag(prec->utag, p->event); - std::cout << "devEvrEventUtag.cpp " - << " p->event " << p->event << " prec->val " << prec->val << " prec->utag " << prec->utag << std::endl; - // #endif +#endif } return 0; diff --git a/evrFRIBApp/src/evr_frib.h b/evrFRIBApp/src/evr_frib.h index bae87a70..cc34c36d 100644 --- a/evrFRIBApp/src/evr_frib.h +++ b/evrFRIBApp/src/evr_frib.h @@ -5,8 +5,8 @@ * * Author: Michael Davidsaver */ -#ifndef SRC_EVR_FRIB_H -#define SRC_EVR_FRIB_H +#ifndef EVR_FRIB_H +#define EVR_FRIB_H #include #include @@ -217,4 +217,4 @@ struct EVRFRIB : public mrf::ObjectInst }; -#endif /* SRC_EVR_FRIB_H */ +#endif // EVR_FRIB_H From 2410f600174b42a6b2dbec17b0ed3c57b10f6eb0 Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Tue, 5 Dec 2023 16:26:22 +0100 Subject: [PATCH 17/23] docs: Copyright added. --- evrApp/src/devEvrEventUtag.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/evrApp/src/devEvrEventUtag.cpp b/evrApp/src/devEvrEventUtag.cpp index 0b0459aa..b8c82678 100644 --- a/evrApp/src/devEvrEventUtag.cpp +++ b/evrApp/src/devEvrEventUtag.cpp @@ -1,3 +1,14 @@ +/*************************************************************************\ +* Copyright (c) 2023 European Spallation Source ERIC (ESS), Lund, Sweden +* mrfioc2 is distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ +/* + * Date: 5.12.2023 + * Authors: Joao Paulo Martins + * Jerzy Jamroz + */ + #include #include #include From 2457330e498baabc33963b4bc673f1e7d2fc423c Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Tue, 5 Dec 2023 16:55:14 +0100 Subject: [PATCH 18/23] fix: $(s=:) was used for the private -ASub_. --- evrApp/Db/evrcml.db | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evrApp/Db/evrcml.db b/evrApp/Db/evrcml.db index 56412a7c..43bf69c2 100644 --- a/evrApp/Db/evrcml.db +++ b/evrApp/Db/evrcml.db @@ -532,13 +532,13 @@ record(bo, "$(ON)BunchTrain$(s=:)Ena-SP") { record(longout, "$(ON)BunchTrain$(s=:)Size-SP") { field(PINI, "YES") - field(OUT , "$(ON)BunchTrain$(s=:)ASub_.A PP") + field(OUT , "$(ON)BunchTrain-ASub_.A PP") field(UDF , "0") field(VAL , "1") info(autosaveFields_pass0, "VAL") } -record(aSub, "$(ON)BunchTrain$(s=:)ASub_") { +record(aSub, "$(ON)BunchTrain-ASub_") { field(SDIS, "$(ON)BunchTrain$(s=:)Ena-SP") field(DISV, "0") field(SNAM, "Bunch Train") From e3b5a60f2b88401af6c2f74e9935c438714dd806 Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Wed, 6 Dec 2023 10:06:27 +0100 Subject: [PATCH 19/23] fix: evreventutag.db included in the module Makefile. --- evrApp/Db/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/evrApp/Db/Makefile b/evrApp/Db/Makefile index d74d6d1a..8899801c 100644 --- a/evrApp/Db/Makefile +++ b/evrApp/Db/Makefile @@ -14,6 +14,9 @@ DB += evrcml.db DB += evrcmlgun.db DB += evrcmlextra.db DB += evrevent.db +ifdef BASE_7_0 +DB += evreventutag.db +endif DB += evrevent-cycle.db DB += evrsoftgate.db DB += evralias.db From bfc6ca25cf8d920a67fb94784465a7b107cad203 Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Thu, 7 Dec 2023 10:07:46 +0100 Subject: [PATCH 20/23] fix: Default VAL=0 for $(EN)-SP added. --- evrApp/Db/evreventutag.db | 1 + 1 file changed, 1 insertion(+) diff --git a/evrApp/Db/evreventutag.db b/evrApp/Db/evreventutag.db index 28612159..237d0041 100644 --- a/evrApp/Db/evreventutag.db +++ b/evrApp/Db/evreventutag.db @@ -11,6 +11,7 @@ record(int64out, "$(EN)-SP") { field(DTYP, "EVR Event Utag") field(SCAN, "I/O Intr") field(OUT , "@OBJ=$(OBJ),Code=$(CODE)") + field(VAL , "0") field(TSE , "-2") # from device support field(FLNK, "$(EN)Cnt-I") info(autosaveFields_pass0, "OUT") From e638c0bb6b96dee583ae065eb5eddec78d59e787 Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Mon, 11 Dec 2023 10:22:23 +0100 Subject: [PATCH 21/23] feat: Warning added which informs if epicsUTag is supported or not. --- evrMrmApp/src/drvem.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/evrMrmApp/src/drvem.cpp b/evrMrmApp/src/drvem.cpp index 755ed93d..94e647a4 100644 --- a/evrMrmApp/src/drvem.cpp +++ b/evrMrmApp/src/drvem.cpp @@ -356,6 +356,10 @@ try{ if(busConfig.busType==busType_pci) mrf::SPIDevice::registerDev(n+":FLASH", mrf::SPIDevice(this, 1)); + #ifndef DBR_UTAG + std::cout << "WARNING EVRMRM::EVRMRM epicsUTag not supported." << std::endl; + #endif + } catch (std::exception& e) { printf("Aborting EVR initializtion: %s\n", e.what()); cleanup(); From 14a7f293fa89711acb7dd91538fed4a1ea0429ec Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Wed, 13 Dec 2023 11:00:14 +0100 Subject: [PATCH 22/23] perf: process_event removed from devEvrEventUtag.cpp. --- evrApp/src/devEvrEventUtag.cpp | 48 +--------------------------------- evrApp/src/evrSupportBase7.dbd | 2 -- 2 files changed, 1 insertion(+), 49 deletions(-) diff --git a/evrApp/src/devEvrEventUtag.cpp b/evrApp/src/devEvrEventUtag.cpp index b8c82678..fb5016d3 100644 --- a/evrApp/src/devEvrEventUtag.cpp +++ b/evrApp/src/devEvrEventUtag.cpp @@ -20,7 +20,6 @@ #include #include -#include #include #include "devObj.h" @@ -115,8 +114,7 @@ static long del_record(struct dbCommon *prec) return ret; } -static long -get_ioint_info(int, dbCommon *prec, IOSCANPVT *io) +static long get_ioint_info(int, dbCommon *prec, IOSCANPVT *io) { if (!prec->dpvt) return S_db_errArg; @@ -180,45 +178,11 @@ static long process_int64out(int64outRecord *prec) return ret; } -static long process_event(eventRecord *prec) -{ - priv *p = static_cast(prec->dpvt); - long ret = 0; - try - { - if (prec->tse == epicsTimeEventDeviceTime) - { - p->evr->getTimeStamp(&prec->time, p->event); -#ifdef DBR_UTAG - prec->utag = p->evr->getUtag(p->event); -#endif - } - - return 0; - } - catch (std::runtime_error &e) - { - recGblRecordError(S_dev_noDevice, (void *)prec, e.what()); - ret = S_dev_noDevice; - } - catch (std::exception &e) - { - recGblRecordError(S_db_noMemory, (void *)prec, e.what()); - ret = S_db_noMemory; - } - return ret; -} - static long add_int64out(struct dbCommon *precord) { return add_record(precord, &((struct int64outRecord *)precord)->out); } -static long add_event(struct dbCommon *precord) -{ - return add_record(precord, &((struct eventRecord *)precord)->inp); -} - dsxt dxtI64OEventUtagEVR = {add_int64out, del_record}; static common_dset devI64OEventUtagEVR = { 6, NULL, @@ -228,17 +192,7 @@ static common_dset devI64OEventUtagEVR = { dset_cast(&process_int64out), NULL}; -dsxt dxtEVEventUtagEVR = {add_event, del_record}; -static common_dset devEVEventUtagEVR = { - 6, NULL, - dset_cast(&init_dset<&dxtEVEventUtagEVR>), - (DEVSUPFUN)init_record_empty, - (DEVSUPFUN)&get_ioint_info, - dset_cast(&process_event), - NULL}; - extern "C" { epicsExportAddress(dset, devI64OEventUtagEVR); - epicsExportAddress(dset, devEVEventUtagEVR); } diff --git a/evrApp/src/evrSupportBase7.dbd b/evrApp/src/evrSupportBase7.dbd index 218a7991..5f1c8c30 100644 --- a/evrApp/src/evrSupportBase7.dbd +++ b/evrApp/src/evrSupportBase7.dbd @@ -1,4 +1,2 @@ # '@C=..., Code=hweventnum' -# device(int64out, INST_IO, devINT64UTAGEVR, "UTAG Source") device(int64out, INST_IO, devI64OEventUtagEVR, "EVR Event Utag") -device(event, INST_IO, devEVEventUtagEVR, "EVR Event Utag") From da6b8b6921877bea73bd80145ed028c3c27ff68f Mon Sep 17 00:00:00 2001 From: Jerzy Jamroz Date: Thu, 14 Dec 2023 10:00:00 +0100 Subject: [PATCH 23/23] refactor: Risk of using a dummy epicsUTag minimilised. --- evrApp/src/evr/evr.h | 7 ++----- evrMrmApp/src/drvem.cpp | 2 ++ evrMrmApp/src/drvem.h | 15 +++++++++------ 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/evrApp/src/evr/evr.h b/evrApp/src/evr/evr.h index 95588258..f42164cd 100644 --- a/evrApp/src/evr/evr.h +++ b/evrApp/src/evr/evr.h @@ -34,11 +34,6 @@ enum TSSource { TSSourceDBus4=2 }; -// Backward compatibility if UTAG is not supported by the epics-base. -#ifndef DBR_UTAG - typedef epicsUInt64 epicsUTag; -#endif - /**@brief Base interface for EVRs. * * This is the interface which the generic EVR device support @@ -196,6 +191,7 @@ class epicsShareClass EVR : public mrf::ObjectInst epicsUInt32 SourceTSraw() const{return (TSSource)SourceTS();}; /*@}*/ +#ifdef DBR_UTAG /**\defgroup utagman UTAG Management * * Get/Set UTAG value for specific event @@ -204,6 +200,7 @@ class epicsShareClass EVR : public mrf::ObjectInst virtual epicsUTag getUtag(const epicsUInt32 event) const {return 0;}; virtual void setUtag(epicsUTag tag, const epicsUInt32 event) {}; /*@}*/ +#endif private: bus_configuration busConfiguration; diff --git a/evrMrmApp/src/drvem.cpp b/evrMrmApp/src/drvem.cpp index 94e647a4..9bbce899 100644 --- a/evrMrmApp/src/drvem.cpp +++ b/evrMrmApp/src/drvem.cpp @@ -1568,6 +1568,7 @@ EVRMRM::seconds_tick(void *raw, epicsUInt32) } } +#ifdef DBR_UTAG // Get UTAG value for specific event epicsUTag EVRMRM::getUtag(const epicsUInt32 event) const { @@ -1589,3 +1590,4 @@ EVRMRM::setUtag(epicsUTag tag, const epicsUInt32 event) { events[event].utag = tag; return; } +#endif diff --git a/evrMrmApp/src/drvem.h b/evrMrmApp/src/drvem.h index c88890ab..46673363 100644 --- a/evrMrmApp/src/drvem.h +++ b/evrMrmApp/src/drvem.h @@ -73,15 +73,18 @@ struct eventCode { bool again; // UTAG associated to event +#ifdef DBR_UTAG epicsUTag utag; - +#endif eventCode():owner(0), interested(0), last_sec(0) - ,last_evt(0), waitingfor(0), again(false), - utag(0) + ,last_evt(0), waitingfor(0), again(false) +#ifdef DBR_UTAG + ,utag(0) +#endif { scanIoInit(&occured); // done_cb - initialized in EVRMRM::EVRMRM() - } + } }; /**@brief Modular Register Map Event Receivers @@ -196,10 +199,10 @@ class epicsShareClass EVRMRM : public mrf::ObjectInst, {SCOPED_LOCK(evrLock);return count_FIFO_sw_overrate;} virtual epicsUInt32 FIFOEvtCount() const OVERRIDE FINAL {return count_fifo_events;} virtual epicsUInt32 FIFOLoopCount() const OVERRIDE FINAL {return count_fifo_loops;} - +#ifdef DBR_UTAG virtual epicsUTag getUtag(const epicsUInt32 event) const OVERRIDE FINAL; virtual void setUtag(epicsUTag tag, const epicsUInt32 event) OVERRIDE FINAL; - +#endif void enableIRQ(void); bool dcEnabled() const;