From 35e9d7d85761d84fe7c041d3d7e402b67a8f5532 Mon Sep 17 00:00:00 2001 From: Alexis Gaget Date: Thu, 11 Jan 2024 17:29:43 +0100 Subject: [PATCH] feat: add sofware and hardware mask/enable for sequencer --- evgMrmApp/Db/evgInput.db | 13 ++ .../Db/evm-mtca-300-evr.uv.substitutions | 124 +++++++++++ evgMrmApp/src/evg.cpp | 5 +- evgMrmApp/src/evgInput.cpp | 20 +- evgMrmApp/src/evgInput.h | 8 + evgMrmApp/src/evgRegMap.h | 10 + iocBoot/iocseqmask/Makefile | 5 + iocBoot/iocseqmask/st_EVM.cmd | 80 +++++++ iocBoot/iocseqmask/st_EVR.cmd | 61 ++++++ mrmShared/Db/mrmSoftSeq.template | 62 ++++++ mrmShared/src/mrmSeq.cpp | 199 +++++++++++++++++- 11 files changed, 583 insertions(+), 4 deletions(-) create mode 100644 iocBoot/iocseqmask/Makefile create mode 100755 iocBoot/iocseqmask/st_EVM.cmd create mode 100755 iocBoot/iocseqmask/st_EVR.cmd diff --git a/evgMrmApp/Db/evgInput.db b/evgMrmApp/Db/evgInput.db index 271793cc..45691d60 100644 --- a/evgMrmApp/Db/evgInput.db +++ b/evgMrmApp/Db/evgInput.db @@ -18,3 +18,16 @@ record(bi, "$(P)EnaIrq-RB") { field( ZNAM, "Disabled") field( ONAM, "Enabled") } + +record(ao, "$(P)FPMask-Sel") { + field( DESC, "FPxMask") + field( DTYP, "Obj Prop uint32") + field( OUT , "@OBJ=$(OBJ), PROP=FPMASK") + field( FLNK, "$(P)FPMask-RB") +} +record(ai, "$(P)FPMask-RB") { + field( DESC, "FPxMask") + field( DTYP, "Obj Prop uint32") + field( INP , "@OBJ=$(OBJ), PROP=FPMASK") +} + diff --git a/evgMrmApp/Db/evm-mtca-300-evr.uv.substitutions b/evgMrmApp/Db/evm-mtca-300-evr.uv.substitutions index b7bc463a..958df2b2 100644 --- a/evgMrmApp/Db/evm-mtca-300-evr.uv.substitutions +++ b/evgMrmApp/Db/evm-mtca-300-evr.uv.substitutions @@ -138,6 +138,130 @@ file "evrpulsermap.db" {31,"\$(P)DlyGen$(PID)EvtTrig0-SP", "$(EVG):EVR$(T):Pul$(PID)", Trig, 0} {31,"\$(P)DlyGen$(PID)EvtTrig1-SP", "$(EVG):EVR$(T):Pul$(PID)", Trig, 0} {31,"\$(P)DlyGen$(PID)EvtTrig2-SP", "$(EVG):EVR$(T):Pul$(PID)", Trig, 0} + +{0, "\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{0, "\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{0, "\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{1, "\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{1, "\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{1, "\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{2, "\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{2, "\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{2, "\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{3, "\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{3, "\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{3, "\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{4, "\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{4, "\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{4, "\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{5, "\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{5, "\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{5, "\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{6, "\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{6, "\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{6, "\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{7, "\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{7, "\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{7, "\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{8, "\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{8, "\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{8, "\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{9, "\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{9, "\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{9, "\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{10,"\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{10,"\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{10,"\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{11,"\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{11,"\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{11,"\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{12,"\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{12,"\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{12,"\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{13,"\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{13,"\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{13,"\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{14,"\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{14,"\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{14,"\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{15,"\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{15,"\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{15,"\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +# gate generators mappings +{28,"\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{28,"\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{28,"\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{29,"\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{29,"\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{29,"\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{30,"\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{30,"\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{30,"\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{31,"\$(P)DlyGen$(PID)EvtSet0-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{31,"\$(P)DlyGen$(PID)EvtSet1-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} +{31,"\$(P)DlyGen$(PID)EvtSet2-SP", "$(EVG):EVR$(T):Pul$(PID)", Set, 0} + +{0, "\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{0, "\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{0, "\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{1, "\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{1, "\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{1, "\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{2, "\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{2, "\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{2, "\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{3, "\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{3, "\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{3, "\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{4, "\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{4, "\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{4, "\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{5, "\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{5, "\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{5, "\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{6, "\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{6, "\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{6, "\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{7, "\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{7, "\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{7, "\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{8, "\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{8, "\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{8, "\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{9, "\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{9, "\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{9, "\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{10,"\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{10,"\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{10,"\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{11,"\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{11,"\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{11,"\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{12,"\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{12,"\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{12,"\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{13,"\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{13,"\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{13,"\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{14,"\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{14,"\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{14,"\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{15,"\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{15,"\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{15,"\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +# gate generators mappings +{28,"\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{28,"\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{28,"\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{29,"\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{29,"\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{29,"\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{30,"\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{30,"\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{30,"\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{31,"\$(P)DlyGen$(PID)EvtReset0-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{31,"\$(P)DlyGen$(PID)EvtReset1-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} +{31,"\$(P)DlyGen$(PID)EvtReset2-SP", "$(EVG):EVR$(T):Pul$(PID)", Reset, 0} } # pulser masking controls diff --git a/evgMrmApp/src/evg.cpp b/evgMrmApp/src/evg.cpp index 00dc7a2c..4783e4f4 100644 --- a/evgMrmApp/src/evg.cpp +++ b/evgMrmApp/src/evg.cpp @@ -27,7 +27,10 @@ OBJECT_BEGIN(evgDbus) { } OBJECT_END(evgDbus) OBJECT_BEGIN(evgInput) { - OBJECT_PROP2("IRQ", &evgInput::getExtIrq, &evgInput::setExtIrq); + OBJECT_PROP2("IRQ", &evgInput::getExtIrq, &evgInput::setExtIrq); + OBJECT_PROP2("FPMASK", &evgInput::getHwMask, &evgInput::setHwMask); + OBJECT_PROP1("FPMASK", &evgInput::stateChange); + } OBJECT_END(evgInput) OBJECT_BEGIN(evgMxc) { diff --git a/evgMrmApp/src/evgInput.cpp b/evgMrmApp/src/evgInput.cpp index fe910ebd..322d04cd 100644 --- a/evgMrmApp/src/evgInput.cpp +++ b/evgMrmApp/src/evgInput.cpp @@ -16,7 +16,9 @@ evgInput::evgInput(const std::string& name, const epicsUInt32 num, ,m_num(num) ,m_type(type) ,m_pInReg(pInReg) -{} +{ + scanIoInit(&changed); +} evgInput::~evgInput() { } @@ -46,6 +48,22 @@ evgInput::getExtIrq() const { return (nat_ioread32(m_pInReg) & (epicsUInt32)EVG_EXT_INP_IRQ_ENA) != 0; } +epicsUInt32 evgInput::getHwMask() const +{ + epicsUInt32 val; + val = (nat_ioread32(m_pInReg) & EVG_INP_FP_MASK) >> EVG_INP_FP_MASK_shift; + return val; +} + +void evgInput::setHwMask(epicsUInt32 src) +{ + epicsUInt32 inReg=nat_ioread32(m_pInReg) & ~(EVG_INP_FP_MASK); + nat_iowrite32(m_pInReg, inReg | (src< 7) diff --git a/evgMrmApp/src/evgInput.h b/evgMrmApp/src/evgInput.h index f63031b7..fcf258bf 100644 --- a/evgMrmApp/src/evgInput.h +++ b/evgMrmApp/src/evgInput.h @@ -7,6 +7,8 @@ #include #include "mrf/object.h" +#include + enum InputType { NoneInp = 0, @@ -31,6 +33,9 @@ class evgInput : public mrf::ObjectInst { void setExtIrq(bool); bool getExtIrq() const; + void setHwMask(epicsUInt32); + epicsUInt32 getHwMask() const; + void setDbusMap(epicsUInt16, bool); bool getDbusMap(epicsUInt16) const; @@ -40,9 +45,12 @@ class evgInput : public mrf::ObjectInst { void setTrigEvtMap(epicsUInt16, bool); bool getTrigEvtMap(epicsUInt16) const; + IOSCANPVT stateChange() const { return changed; } + private: const epicsUInt32 m_num; const InputType m_type; volatile epicsUInt8* const m_pInReg; + IOSCANPVT changed; }; #endif //EVG_INPUT_H diff --git a/evgMrmApp/src/evgRegMap.h b/evgMrmApp/src/evgRegMap.h index 6d5f88a4..0ac3e937 100644 --- a/evgMrmApp/src/evgRegMap.h +++ b/evgMrmApp/src/evgRegMap.h @@ -259,6 +259,12 @@ #define EVG_SEQ_RAM_SINGLE 0x00100000 // Single-Shot Mode: Disable on completion #define EVG_SEQ_RAM_RECYCLE 0x00080000 // Continuous Mode: Repeat on completion +//Mask registers +#define EVG_SEQ_RAM_SWMASK 0x0000F000 // Sequence RAM Software mask +#define EVG_SEQ_RAM_SWMASK_shift 12 +#define EVG_SEQ_RAM_SWENABLE 0x00000F00 // Sequence RAM Software enable +#define EVG_SEQ_RAM_SWENABLE_shift 8 + /**************************************************************************************************/ /* Control Register flags */ /**************************************************************************************************/ @@ -275,6 +281,10 @@ /**************************************************************************************************/ #define EVG_EXT_INP_IRQ_ENA 0x01000000 +#define EVG_INP_FP_ENA 0x0F000000 +#define EVG_INP_FP_ENA_shift 24 +#define EVG_INP_FP_MASK 0xF0000000 +#define EVG_INP_FP_MASK_shift 28 #ifndef EVG_CONSTANTS #define EVG_CONSTANTS diff --git a/iocBoot/iocseqmask/Makefile b/iocBoot/iocseqmask/Makefile new file mode 100644 index 00000000..79c4ce6e --- /dev/null +++ b/iocBoot/iocseqmask/Makefile @@ -0,0 +1,5 @@ +TOP = ../.. +include $(TOP)/configure/CONFIG +ARCH = linux-x86_64 +TARGETS = envPaths +include $(TOP)/configure/RULES.ioc diff --git a/iocBoot/iocseqmask/st_EVM.cmd b/iocBoot/iocseqmask/st_EVM.cmd new file mode 100755 index 00000000..32daaad4 --- /dev/null +++ b/iocBoot/iocseqmask/st_EVM.cmd @@ -0,0 +1,80 @@ +#!../../bin/linux-x86_64/mrf + +< envPaths + +## Register all support components +dbLoadDatabase("../../dbd/mrf.dbd") +mrf_registerRecordDeviceDriver(pdbbase) + +epicsEnvSet("IOCSH_PS1","EVM SeqMask> ") +epicsEnvSet("P","Ether-Realm:EVM") +epicsEnvSet("ENGINEER","agaget") +epicsEnvSet("LOCATION","Etheric Realm") + +epicsEnvSet("EPICS_CA_MAX_ARRAY_BYTES","10000000") + +epicsEnvSet("EVM_PCI","0000:0e:00.0") +epicsEnvSet("PORT","EVM-MTCA") +epicsEnvSet(FREQ, "88") + +mrmEvgSetupPCI("$(PORT)", "$(EVM_PCI)") + +## Load record instances +cd $(TOP) +dbLoadRecords("db/evm-mtca-300.uv.db","P=$(P):,s=,EVG=$(PORT),FRF=$(FREQ),FEVT=$(FREQ)") +dbLoadRecords("db/evm-mtca-300-evr.uv.db","P=$(P)U:,EVG=$(PORT),T=U,FRF=$(FREQ),FEVT=$(FREQ)") +dbLoadRecords("db/evm-mtca-300-evr.uv.db","P=$(P)D:,EVG=$(PORT),T=D,FRF=$(FREQ),FEVT=$(FREQ)") + +iocInit() + +##### Configure the EVM +dbpf $(P):Mxc0Frequency-SP 1 +dbpf $(P):Mxc0Prescaler-SP 88000000 +## Configure the sequencer +dbpf $(P):SoftSeq0TrigSrc0-Sel "Mxc0" +dbpf $(P):SoftSeq0TsResolution-Sel "uSec" +dbpf $(P):SoftSeq0RunMode-Sel "Normal" + +dbpf $(P):SoftSeq0Timestamp-SP "[100, 200]" +#Can't dbpf waveform of UCHAR so we use this. Change architecture if needed. +#Event 11 is just used for example +system("$(EPICS_BASE)/bin/linux-x86_64/caput -a $(P):SoftSeq0EvtCode-SP 2 1 11") +system("$(EPICS_BASE)/bin/linux-x86_64/caput -a $(P):SoftSeq0EvtMask-SP 2 1 0") +# Due to this 'enable' settings, event 11 will not b triggered by default +system("$(EPICS_BASE)/bin/linux-x86_64/caput -a $(P):SoftSeq0EvtEna-SP 2 0 3") + +# To fully understand mask and enable I suggest you to play with software mask an enable an watch counter of the EVR: +# $(P):SoftSeq0SwMask-Sel +# $(P):SoftSeq0SwEna-Sel +# If you put soft mask to 1 or 3 or 5 etc... it will mask event 1 of the sequence +# because mask of the sequencer is 1, and it's (binary) included in the software mask number +# For enable, soft ena to 3 or 7 or 11.. will enable event 11 of the sequencer +# because ena of the sequencer is 3 and it's (binary) included in the software ena number + +## Configure the EVRU +dbpf $(P)U:DlyGen0EvtSet0-SP 13 +dbpf $(P)U:DlyGen0EvtReset0-SP 14 +dbpf $(P)U:OutFP0SrcPulse-SP "Pulser 0" +# FP0 of the EVRU is the equivalent of Univ8 of the EVM +# So this triggered the Mask 1 when FP0/Univ8 is High. +dbpf $(P):InpUniv8FPMask-Sel "1" + + +epicsThreadSleep(1) + +dbtr $(P):SoftSeq0Commit-Cmd + +epicsThreadSleep(1) + +dbpf $(P):SoftSeq0Load-Cmd 1 +dbpf $(P):SoftSeq0Enable-Cmd 1 + +# dbpf $(P):TrigEvt1TrigSrc0-Sel Mxc0 +# dbpf $(P):TrigEvt0EvtCode-SP 1 + +## Push event 13 just to see that upstream/downstream is working +dbpf $(P):TrigEvt1TrigSrc1-Sel Univ8 +dbpf $(P):TrigEvt1EvtCode-SP 13 + +## + diff --git a/iocBoot/iocseqmask/st_EVR.cmd b/iocBoot/iocseqmask/st_EVR.cmd new file mode 100755 index 00000000..350f45f4 --- /dev/null +++ b/iocBoot/iocseqmask/st_EVR.cmd @@ -0,0 +1,61 @@ +#!../../bin/linux-x86_64/mrf + +< envPaths + +## Register all support components +dbLoadDatabase("../../dbd/mrf.dbd") +mrf_registerRecordDeviceDriver(pdbbase) + +epicsEnvSet("IOCSH_PS1","EVR SeqMask> ") +epicsEnvSet("P","Ether-Realm:EVR") +epicsEnvSet("ENGINEER","agaget") +epicsEnvSet("LOCATION","Etheric Realm") + +epicsEnvSet("EPICS_CA_MAX_ARRAY_BYTES","10000000") + +epicsEnvSet("EVR_PCI","0000:0c:00.0") + + +mrmEvrSetupPCI("EVR-MTCA", "$(EVR_PCI)") + +cd $(TOP) +## Load record instances +dbLoadRecords("db/evr-mtca-300u.uv.db","P=$(P):,EVR=EVR-MTCA,PNDELAY=PNDELAY,PNWIDTH=PNWIDTH,FRF=88,FEVT=88") + + +iocInit() + +## we use Backplane of the MTCA card here to upstream event through input, like that no need for any other phyical installation. +## Events 2 and 3 will be use to mask and unmask the event 1 in the sequencer. You can send them softwarely through the EVM. +## Indeed You can remove that part and use analogic signal in other inputs if you prefer. +### When we receive event 2 Pulser 1-> backplane 1 is triggered +dbpf $(P):DlyGen1Width-SP 100 +dbpf $(P):DlyGen1Width-RB +dbpf $(P):DlyGen1EvtTrig0-SP 2 +dbpf $(P):OutBack1SrcPulse-SP "Pulser 1" + +#When we receive event 3 Pulser 2-> backplane 2 is triggered +dbpf $(P):DlyGen2Width-SP 100 +dbpf $(P):DlyGen2Width-RB +dbpf $(P):DlyGen2EvtTrig0-SP 3 +dbpf $(P):OutBack2SrcPulse-SP "Pulser 2" + +###Backplane channel 1 use for masking +dbpf $(P):BPIn1TrigBack-Sel "Edge" +dbpf $(P):BPIn1CodeBack-SP 13 + +###Backplane channel 2 use for unmasking +dbpf $(P):BPIn2TrigBack-Sel "Edge" +dbpf $(P):BPIn2CodeBack-SP 14 + +## Monitoring events. When your sequencer is running normally, counter A should increment at 1Hz. +## When event 2 is send to this EVR, counterA will stop incrementing, counterB will increment + 1, and counterD will increment +1 +## When event 3 is send to this EVR, counterA will restart incrementing, counterC will increment + 1 +dbpf $(P):EvtA-SP.OUT "@OBJ=EVR-MTCA,Code=1" +dbpf $(P):EvtB-SP.OUT "@OBJ=EVR-MTCA,Code=2" +dbpf $(P):EvtC-SP.OUT "@OBJ=EVR-MTCA,Code=3" +dbpf $(P):EvtD-SP.OUT "@OBJ=EVR-MTCA,Code=13" +dbpf $(P):EvtE-SP.OUT "@OBJ=EVR-MTCA,Code=11" + +## + diff --git a/mrmShared/Db/mrmSoftSeq.template b/mrmShared/Db/mrmSoftSeq.template index daddd962..76d40a94 100644 --- a/mrmShared/Db/mrmSoftSeq.template +++ b/mrmShared/Db/mrmSoftSeq.template @@ -60,6 +60,42 @@ record(mbbi, "$(P)TsResolution-RB") { field( UNSV, "INVALID") } +record(waveform, "$(P)EvtEna-SP") { + field( DTYP, "Obj Prop waveform out") + field( DESC, "Sequence event enable array") + field( INP, "@OBJ=$(EVG):SEQ$(seqNum), CLASS=SeqManager, PARENT=$(EVG):SEQMGR, PROP=ENA") + field( NELM, "$(NELM)") + field( FTVL, "UCHAR") + info( autosaveFields_pass1, "VAL") +} + +record(waveform, "$(P)EvtEna-RB") { + field( DTYP, "Obj Prop waveform in") + field( DESC, "Sequence event enable readback") + field( INP, "@OBJ=$(EVG):SEQ$(seqNum), CLASS=SeqManager, PARENT=$(EVG):SEQMGR, PROP=ENA") + field( SCAN, "I/O Intr") + field( NELM, "$(NELM)") + field( FTVL, "UCHAR") +} + +record(waveform, "$(P)EvtMask-SP") { + field( DTYP, "Obj Prop waveform out") + field( DESC, "Sequence event mask array") + field( INP, "@OBJ=$(EVG):SEQ$(seqNum), CLASS=SeqManager, PARENT=$(EVG):SEQMGR, PROP=MASK") + field( NELM, "$(NELM)") + field( FTVL, "UCHAR") + info( autosaveFields_pass1, "VAL") +} + +record(waveform, "$(P)EvtMask-RB") { + field( DTYP, "Obj Prop waveform in") + field( DESC, "Sequence event mask readback") + field( INP, "@OBJ=$(EVG):SEQ$(seqNum), CLASS=SeqManager, PARENT=$(EVG):SEQMGR, PROP=MASK") + field( SCAN, "I/O Intr") + field( NELM, "$(NELM)") + field( FTVL, "UCHAR") +} + record(waveform, "$(P)EvtCode-SP") { field( DTYP, "Obj Prop waveform out") field( DESC, "Sequence event code array") @@ -213,6 +249,32 @@ record(bo, "$(P)SoftTrig-Cmd") { field( ONAM, "1") } +record(mbbo, "$(P)SwMask-Sel") { + field( DTYP, "Obj Prop uint32") + field( DESC, "Sequence RAM soft trigger") + field( OUT, "@OBJ=$(EVG):SEQ$(seqNum), CLASS=SeqManager, PARENT=$(EVG):SEQMGR, PROP=SWMASK") +} + +record(mbbi, "$(P)SwMask-RB") { + field( DTYP, "Obj Prop uint32") + field( DESC, "Sequence RAM soft trigger") + field( INP, "@OBJ=$(EVG):SEQ$(seqNum), CLASS=SeqManager, PARENT=$(EVG):SEQMGR, PROP=SWMASK") + field( SCAN, "I/O Intr") +} + +record(mbbo, "$(P)SwEna-Sel") { + field( DTYP, "Obj Prop uint32") + field( DESC, "Sequence RAM soft trigger") + field( OUT, "@OBJ=$(EVG):SEQ$(seqNum), CLASS=SeqManager, PARENT=$(EVG):SEQMGR, PROP=SWENA") +} + +record(mbbi, "$(P)SwEna-RB") { + field( DTYP, "Obj Prop uint32") + field( DESC, "Sequence RAM soft trigger") + field( INP, "@OBJ=$(EVG):SEQ$(seqNum), CLASS=SeqManager, PARENT=$(EVG):SEQMGR, PROP=SWENA") + field( SCAN, "I/O Intr") +} + record(bi, "$(P)Load-RB") { field( DTYP, "Obj Prop bool") field( DESC, "Soft Seq Load status") diff --git a/mrmShared/src/mrmSeq.cpp b/mrmShared/src/mrmSeq.cpp index 8525ccf1..9bb16949 100644 --- a/mrmShared/src/mrmSeq.cpp +++ b/mrmShared/src/mrmSeq.cpp @@ -30,6 +30,11 @@ #define EVG_SEQ_RAM_DISABLE 0x00020000 /* Sequence RAM Disable (and stop) */ #define EVG_SEQ_RAM_ARM 0x00010000 /* Sequence RAM Enable/Arm */ +#define EVG_SEQ_RAM_SWMASK 0x0000F000 // Sequence RAM Software mask +#define EVG_SEQ_RAM_SWMASK_shift 12 +#define EVG_SEQ_RAM_SWENABLE 0x00000F00 // Sequence RAM Software enable +#define EVG_SEQ_RAM_SWENABLE_shift 8 + #define EVG_SEQ_RAM_WRITABLE_MASK 0x00ffffff #define EVG_SEQ_RAM_REPEAT_MASK 0x00180000 /* Sequence RAM Repeat Mode Mask */ #define EVG_SEQ_RAM_NORMAL 0x00000000 /* Normal Mode: Repeat every trigger */ @@ -254,6 +259,68 @@ struct SoftSequence : public mrf::ObjectInst return ret; } + void setMask(const epicsUInt8 *arr, epicsUInt32 count) + { + masks_t masks(count); + if (*arr>15){ + std::string msg("4 bits code. Authorized range is [0-15]"); + last_err = msg; + scanIoRequest(onErr); + throw std::runtime_error(msg); + } + std::copy(arr, + arr + count, + masks.begin()); + { + SCOPED_LOCK(mutex); + scratch.masks.swap(masks); + is_committed = false; + } + DEBUG(4, ("Set masks\n")); + scanIoRequest(changed); + } + + epicsUInt32 getMask(epicsUInt8 *arr, epicsUInt32 count) const + { + SCOPED_LOCK(mutex); + epicsUInt32 ret = std::min(size_t(count), committed.masks.size()); + std::copy(committed.masks.begin(), + committed.masks.begin() + ret, + arr); + return ret; + } + + void setEna(const epicsUInt8 *arr, epicsUInt32 count) + { + if (*arr>15){ + std::string msg("4 bits code. Authorized range is [0-15]"); + last_err = msg; + scanIoRequest(onErr); + throw std::runtime_error(msg); + } + enables_t enables(count); + std::copy(arr, + arr + count, + enables.begin()); + { + SCOPED_LOCK(mutex); + scratch.enables.swap(enables); + is_committed = false; + } + DEBUG(4, ("Set enables\n")); + scanIoRequest(changed); + } + + epicsUInt32 getEna(epicsUInt8 *arr, epicsUInt32 count) const + { + SCOPED_LOCK(mutex); + epicsUInt32 ret = std::min(size_t(count), committed.enables.size()); + std::copy(committed.enables.begin(), + committed.enables.begin() + ret, + arr); + return ret; + } + void setTrigSrc(epicsUInt32 src) { DEBUG(4, ("Setting trig src %x\n", (unsigned)src)); @@ -314,6 +381,12 @@ struct SoftSequence : public mrf::ObjectInst void enable(); void disable(); void softTrig(); + + epicsUInt32 getSwMask() const; + void setSwMask(epicsUInt32 src); + epicsUInt32 getSwEna() const; + void setSwEna(epicsUInt32 src); + epicsUInt32 counterStart() const { interruptLock L; return numStart; } IOSCANPVT counterStartScan() const { return onStart; } @@ -335,10 +408,14 @@ struct SoftSequence : public mrf::ObjectInst typedef std::vector times_t; typedef std::vector codes_t; + typedef std::vector masks_t; + typedef std::vector enables_t; struct Config { times_t times; codes_t codes; + masks_t masks; + enables_t enables; RunMode mode; epicsUInt32 src; Config() @@ -349,6 +426,8 @@ struct SoftSequence : public mrf::ObjectInst { std::swap(times, o.times); std::swap(codes, o.codes); + std::swap(masks, o.masks); + std::swap(enables, o.enables); std::swap(mode, o.mode); std::swap(src, o.src); } @@ -387,11 +466,19 @@ OBJECT_BEGIN(SoftSequence) OBJECT_PROP1("COMMITTED", &SoftSequence::isCommited); OBJECT_PROP1("COMMITTED", &SoftSequence::stateChange); OBJECT_PROP1("COMMIT", &SoftSequence::commit); + OBJECT_PROP2("SWMASK", &SoftSequence::getSwMask, &SoftSequence::setSwMask); + OBJECT_PROP1("SWMASK", &SoftSequence::stateChange); + OBJECT_PROP2("SWENA", &SoftSequence::getSwEna, &SoftSequence::setSwEna); + OBJECT_PROP1("SWENA", &SoftSequence::stateChange); OBJECT_PROP1("SOFT_TRIG", &SoftSequence::softTrig); OBJECT_PROP2("TIMES", &SoftSequence::getTimestamp, &SoftSequence::setTimestamp); OBJECT_PROP1("TIMES", &SoftSequence::stateChange); OBJECT_PROP2("CODES", &SoftSequence::getEventCode, &SoftSequence::setEventCode); OBJECT_PROP1("CODES", &SoftSequence::stateChange); + OBJECT_PROP2("MASK", &SoftSequence::getMask, &SoftSequence::setMask); + OBJECT_PROP1("MASK", &SoftSequence::stateChange); + OBJECT_PROP2("ENA", &SoftSequence::getEna, &SoftSequence::setEna); + OBJECT_PROP1("ENA", &SoftSequence::stateChange); OBJECT_PROP1("NUM_RUNS", &SoftSequence::counterEnd); OBJECT_PROP1("NUM_RUNS", &SoftSequence::counterEndScan); OBJECT_PROP1("NUM_STARTS", &SoftSequence::counterStart); @@ -435,6 +522,97 @@ void SoftSequence::softTrig() DEBUG(2, ("SW Triggered\n") ); } +epicsUInt32 SoftSequence::getSwMask() const +{ + epicsUInt32 val; + + DEBUG(3, ("SW Mask getter\n")); + SCOPED_LOCK(mutex); + if (!hw || !is_enabled) + { + DEBUG(3, ("Skip\n")); + return 0; + } + + else + { + DEBUG(5, ("Register sequencer : %u\n", nat_ioread32(hw->ctrlreg))); + epicsUInt32 val = (nat_ioread32(hw->ctrlreg) & EVG_SEQ_RAM_SWMASK) >> EVG_SEQ_RAM_SWMASK_shift; + DEBUG(5, ("Response sequencer : %u\n", val)); + return val; + } +} + +void SoftSequence::setSwMask(epicsUInt32 src) +{ + + if (src>15){ + std::string msg("4 bits code. Authorized range is [0-15]"); + last_err = msg; + scanIoRequest(onErr); + throw std::runtime_error(msg); + } + DEBUG(3, ("SW Mask setter\n")); + if (!hw || !is_enabled) + { + DEBUG(3, ("Skip\n")); + return; + } + + else + { + hw->ctrlreg_hw &= ~(EVG_SEQ_RAM_SWMASK); + hw->ctrlreg_hw |= src << EVG_SEQ_RAM_SWMASK_shift; + nat_iowrite32(hw->ctrlreg, hw->ctrlreg_hw); + scanIoRequest(changed); + } +} + +epicsUInt32 SoftSequence::getSwEna() const +{ + epicsUInt32 val; + + DEBUG(3, ("SW Enable getter\n")); + SCOPED_LOCK(mutex); + if (!hw || !is_enabled) + { + DEBUG(3, ("Skip\n")); + return 0; + } + + else + { + DEBUG(5, ("Register sequencer : %u\n", nat_ioread32(hw->ctrlreg))); + epicsUInt32 val = (nat_ioread32(hw->ctrlreg) & EVG_SEQ_RAM_SWENABLE) >> EVG_SEQ_RAM_SWENABLE_shift; + DEBUG(5, ("Response sequencer : %u\n", val)); + return val; + } +} + +void SoftSequence::setSwEna(epicsUInt32 src) +{ + if (src>15){ + std::string msg("4 bits code. Authorized range is [0-15]"); + last_err = msg; + scanIoRequest(onErr); + throw std::runtime_error(msg); + } + DEBUG(3, ("SW Enable setter\n")); + if (!hw || !is_enabled) + { + DEBUG(3, ("Skip\n")); + return; + } + else + { + hw->ctrlreg_hw &= ~(EVG_SEQ_RAM_SWENABLE); + hw->ctrlreg_hw |= src << EVG_SEQ_RAM_SWENABLE_shift; + nat_iowrite32(hw->ctrlreg, hw->ctrlreg_hw); + scanIoRequest(changed); + } +} + + void SoftSequence::load() { SCOPED_LOCK(mutex); @@ -519,6 +697,8 @@ void SoftSequence::commit() conf.times.size()); conf.codes.resize(buflen); conf.times.resize(buflen); + conf.enables.resize(buflen); + conf.masks.resize(buflen); // ensure presence of trailing end of sequence marker event 0x7f if(conf.codes.empty() || conf.codes.back()!=0x7f) @@ -536,6 +716,10 @@ void SoftSequence::commit() conf.times.push_back(0); else conf.times.push_back(conf.times.back()+1); + + conf.masks.push_back(0); + conf.enables.push_back(0); + } if(conf.times.size()>2048) { @@ -698,10 +882,21 @@ void SoftSequence::sync() volatile epicsUInt32 *ram = static_cast(hw->rambase); for(size_t i=0, N=committed.codes.size(); i