Skip to content

Commit

Permalink
feat: Timestaming with UTAG #107 from jerzyjamroz/utag-rc
Browse files Browse the repository at this point in the history
  • Loading branch information
jerzyjamroz authored Dec 14, 2023
2 parents 55198e9 + da6b8b6 commit 7f59d47
Show file tree
Hide file tree
Showing 9 changed files with 290 additions and 4 deletions.
3 changes: 3 additions & 0 deletions evrApp/Db/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions evrApp/Db/evrcml.db
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
27 changes: 27 additions & 0 deletions evrApp/Db/evreventutag.db
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# 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
# 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(VAL , "0")
field(TSE , "-2") # from device support
field(FLNK, "$(EN)Cnt-I")
info(autosaveFields_pass0, "OUT")
}

record(calc, "$(EN)Cnt-I") {
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")
}
7 changes: 7 additions & 0 deletions evrApp/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ evr_SRCS += evrGTIF.cpp

evr_SRCS += devEvrStringIO.cpp

ifdef BASE_7_0
evr_SRCS += devEvrEventUtag.cpp
endif

evr_SRCS += devEvrEvent.cpp
evr_SRCS += devEvrMapping.cpp

Expand All @@ -53,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
Expand Down
198 changes: 198 additions & 0 deletions evrApp/src/devEvrEventUtag.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
/*************************************************************************\
* 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 <joaopaulosm@gmail.com>
* Jerzy Jamroz <jerzy.jamroz@gmail.com>
*/

#include <stdlib.h>
#include <string.h>
#include <epicsExport.h>
#include <dbAccess.h>
#include <devSup.h>
#include <recGbl.h>
#include <devLib.h> // For S_dev_*
#include <alarm.h>
#include <errlog.h>

#include <int64outRecord.h>
#include <epicsVersion.h>

#include "devObj.h"
#include "evr/evr.h"

#include "linkoptions.h"

#include <stdexcept>
#include <string>

/***************** 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<priv> 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<EVR *>(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<priv *>(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<priv *>(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<priv *>(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<epicsUTag>(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);
}
11 changes: 11 additions & 0 deletions evrApp/src/evr/evr.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,17 @@ class epicsShareClass EVR : public mrf::ObjectInst<EVR>
epicsUInt32 SourceTSraw() const{return (TSSource)SourceTS();};
/*@}*/

#ifdef DBR_UTAG
/**\defgroup utagman UTAG Management
*
* Get/Set UTAG value for specific event
*/
/*@{*/
virtual epicsUTag getUtag(const epicsUInt32 event) const {return 0;};
virtual void setUtag(epicsUTag tag, const epicsUInt32 event) {};
/*@}*/
#endif

private:
bus_configuration busConfiguration;
}; // class EVR
Expand Down
2 changes: 2 additions & 0 deletions evrApp/src/evrSupportBase7.dbd
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# '@C=..., Code=hweventnum'
device(int64out, INST_IO, devI64OEventUtagEVR, "EVR Event Utag")
28 changes: 28 additions & 0 deletions evrMrmApp/src/drvem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -1563,3 +1567,27 @@ EVRMRM::seconds_tick(void *raw, epicsUInt32)
callbackRequest(&evr->timeSrc_cb);
}
}

#ifdef DBR_UTAG
// Get UTAG value for specific event
epicsUTag
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);

return events[event].utag;
}

// Set UTAG value for specific event
void
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);

// set UTAG value to particular event
events[event].utag = tag;
return;
}
#endif
14 changes: 12 additions & 2 deletions evrMrmApp/src/drvem.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,19 @@ struct eventCode {
size_t waitingfor;
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)
#ifdef DBR_UTAG
,utag(0)
#endif
{
scanIoInit(&occured);
// done_cb - initialized in EVRMRM::EVRMRM()
}
}
};

/**@brief Modular Register Map Event Receivers
Expand Down Expand Up @@ -192,7 +199,10 @@ class epicsShareClass EVRMRM : public mrf::ObjectInst<EVRMRM, EVR>,
{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;
Expand Down

0 comments on commit 7f59d47

Please sign in to comment.