21 #include <epicsInterrupt.h> 22 #include <epicsTime.h> 23 #include <generalTimeSup.h> 24 #include <epicsStdio.h> 26 #include <longoutRecord.h> 31 #include "mrf/version.h" 36 #include <rtems/bspIo.h> 41 #include <epicsExport.h> 45 "mTCA-EVM-300 (EVRU)",
60 "mTCA-EVM-300 (EVRD)",
76 volatile epicsUInt8*
const pReg,
77 const epicsPCIDevice *pciDevice):
83 m_pciDevice(pciDevice),
86 busConfiguration(busConfig),
90 m_ClkSrc(ClkSrcInternal),
92 m_acTrig(id+
":AcTrig", pReg),
93 shadowIrqEnable(
READ32(m_pReg, IrqEnable))
102 throw std::runtime_error(
"Address does not correspond to an EVG");
105 std::ostringstream
name;
106 name<<
id<<
":TrigEvt"<<i;
107 m_trigEvt.push_back(
new evgTrigEvt(name.str(), i, pReg));
111 std::ostringstream
name;
113 m_muxCounter.push_back(
new evgMxc(name.str(), i,
this));
117 std::ostringstream
name;
118 name<<
id<<
":Dbus"<<i;
119 m_dbus.push_back(
new evgDbus(name.str(), i, pReg));
123 std::ostringstream
name;
124 name<<
id<<
":FrontInp"<<i;
125 m_input[ std::pair<epicsUInt32, InputType>(i,
FrontInp) ] =
129 for(
unsigned i = 0; i < conf->
numUnivInp; i++) {
130 std::ostringstream
name;
131 name<<
id<<
":UnivInp"<<i;
132 m_input[ std::pair<epicsUInt32, InputType>(i,
UnivInp) ] =
136 for(
unsigned i = 0; i < conf->
numRearInp; i++) {
137 std::ostringstream
name;
138 name<<
id<<
":RearInp"<<i;
139 m_input[ std::pair<epicsUInt32, InputType>(i,
RearInp) ] =
144 std::ostringstream
name;
145 name<<
id<<
":FrontOut"<<i;
146 m_output[std::pair<epicsUInt32, evgOutputType>(i,
FrontOut)] =
151 std::ostringstream
name;
152 name<<
id<<
":UnivOut"<<i;
153 m_output[std::pair<epicsUInt32, evgOutputType>(i,
UnivOut)] =
165 printf(
"EVM automatically creating '%s:FCT', '%s:EVRD', and '%s:EVRU'\n",
id.c_str(),
id.c_str(),
id.c_str());
166 fct.reset(
new FCT(
this,
id+
":FCT", pReg+0x10000));
167 evrd.reset(
new EVRMRM(
id+
":EVRD", busConfig, &evm_evrd_conf, pReg+0x20000, 0x10000));
168 evru.reset(
new EVRMRM(
id+
":EVRU", busConfig, &evm_evru_conf, pReg+0x30000, 0x10000));
176 for(
size_t i = 0; i < m_trigEvt.size(); i++)
179 for(
size_t i = 0; i < m_muxCounter.size(); i++)
180 delete m_muxCounter[i];
182 for(
size_t i = 0; i < m_dbus.size(); i++)
185 while(!m_input.empty())
186 m_input.erase(m_input.begin());
188 while(!m_output.empty())
189 m_output.erase(m_output.begin());
202 WRITE32(m_pReg, IrqEnable, shadowIrqEnable);
207 callbackSetPriority(priority, ptr);
208 callbackSetCallback(fn, ptr);
209 callbackSetUser(valptr, ptr);
240 return READ32(m_pReg, Status)>>16;
246 throw std::runtime_error(
"Unsupported mode");
249 epicsUInt32 ctrl =
NAT_READ32(m_pReg, Control);
265 epicsUInt32 ctrl =
NAT_READ32(m_pReg, Control);
286 #if defined(__linux__) || defined(_WIN32) 292 printf(
"PCI: Failed to enable interrupt\n");
303 evg->
isr(evg,
false);
317 epicsUInt32 flags =
READ32(evg->m_pReg, IrqFlag);
318 epicsUInt32 active = flags & evg->shadowIrqEnable;
320 #if defined(vxWorks) || defined(__rtems__) 324 printk(
"evgMrm::isr with no active VME IRQ 0x%08x 0x%08x\n", flags, evg->shadowIrqEnable);
359 evg->shadowIrqEnable &= ~EVG_IRQ_EXT_INP;
365 WRITE32(evg->m_pReg, IrqFlag, flags);
366 READ32(evg->m_pReg, IrqFlag);
369 epicsInterruptContextMessage(
"c++ Exception in ISR!!!\n");
376 callbackGetUser(pVoid, pCallback);
402 throw std::runtime_error(
"Event Code out of range. Valid range: 0 - 255.");
417 evgInput* inp = m_input[ std::pair<epicsUInt32, InputType>(inpNum, type) ];
419 throw std::runtime_error(
"Input not initialized");
426 return &m_timerEvent;
431 return &busConfiguration;
epicsEvent * getTimerEvent()
std::string getFwVersionStr() const
#define BITSET32(base, offset, mask)
#define PCI_DEVICE_ID_MRF_MTCA_EVM_300
static void isr_vme(void *)
#define U16_FrontOutMap(n)
#define U32_FrontInMap(n)
#define EVG_IRQ_STOP_RAM(N)
std::string getSwVersion() const
#define READ32(base, offset)
static void registerDev(const std::string &name, const SPIDevice &)
#define U16_UnivOutMap(n)
void setEvtCode(epicsUInt32)
#define EVG_IRQ_START_RAM(N)
#define SwEvent_Code_SHIFT
void doStartOfSequence(unsigned i)
Call from ISR.
Modular Register Map Event Receivers.
static void process_inp_cb(CALLBACK *)
volatile epicsUInt8 * getRegAddr() const
void resetMxc(bool reset)
#define U8_DataBuffer_base
void doEndOfSequence(unsigned i)
Call from ISR.
IOSCANPVT ioScanTimestamp
void tickSecond()
Call just after the start of each second.
static void isr_poll(void *)
epicsUInt32 getDbusStatus() const
virtual void postSoftSecondsSrc()
unsigned char irqExtInp_queued
#define NAT_READ32(base, offset)
const bus_configuration * getBusConfiguration()
evgInput * getInput(epicsUInt32, InputType)
#define U32_DataBufferControl
const epicsPCIDevice * m_pciDevice
static void unregisterDev(const std::string &name)
const std::string & name() const
#define FPGAVersion_TYPE_SHIFT
static void init_cb(CALLBACK *, int, void(*)(CALLBACK *), void *)
static void isr(evgMrm *evg, bool pci)
#define NAT_WRITE32(base, offset, value)
const std::string getId() const
epicsUInt16 enabled() const
static void isr_pci(void *)
evgMrm(const std::string &id, const Config *conf, bus_configuration &busConfig, volatile epicsUInt8 *const base, const epicsPCIDevice *pciDevice)
#define WRITE32(base, offset, value)
#define FPGAVersion_TYPE_MASK
MRFVersion version() const