mrfioc2  2.6.0
Functions | Variables
drvemIocsh.h File Reference
#include <initHooks.h>
#include <shareLib.h>
Include dependency graph for drvemIocsh.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void epicsShareFunc mrmEvrSetupPCI (const char *id, const char *pcispec, const char *mtca_evr_model)
 
void epicsShareFunc mrmEvrSetupVME (const char *id, int slot, int base, int level, int vector)
 
void epicsShareFunc mrmEvrDumpMap (const char *id, int evt, int ram)
 
void epicsShareFunc mrmEvrForward (const char *id, const char *events_iocsh)
 Setup Event forwarding to downstream link. More...
 
void epicsShareFunc mrmEvrLoopback (const char *id, int rxLoopback, int txLoopback)
 
void epicsShareFunc mrmEvrInithooks (initHookState state)
 
long epicsShareFunc mrmEvrReport (int level)
 
void epicsShareFunc mrmEvrProbe (const char *id)
 

Variables

epicsShareExtern int evrmrmVerb
 Extra noise control. More...
 

Function Documentation

◆ mrmEvrDumpMap()

void epicsShareFunc mrmEvrDumpMap ( const char *  id,
int  evt,
int  ram 
)

Definition at line 947 of file drvemSetup.cpp.

948 {
949 try {
951  if(!obj)
952  throw std::runtime_error("Object not found");
953  EVRMRM *card=dynamic_cast<EVRMRM*>(obj);
954  if(!card)
955  throw std::runtime_error("Not a MRM EVR");
956 
957  printf("Print ram #%d\n",ram);
958  if(evt>=0){
959  // Print a single event
960  printRamEvt(card,evt,ram);
961  return;
962  }
963  for(evt=0;evt<=255;evt++){
964  printRamEvt(card,evt,ram);
965  }
966 } catch(std::exception& e) {
967  printf("Error: %s\n",e.what());
968 }
969 }
Modular Register Map Event Receivers.
Definition: drvem.h:94
Base object inspection.
Definition: object.h:378
static Object * getObject(const std::string &name)
Definition: object.cpp:107

◆ mrmEvrForward()

void epicsShareFunc mrmEvrForward ( const char *  id,
const char *  events_iocsh 
)

Setup Event forwarding to downstream link.

Control which events will be forwarded to the downstream event link when they are received on the upstream link. Useful when daisy chaining EVRs.

When invoked with the second argument as NULL or "" the current forward mapping is printed.

The second argument to this function is a comma seperated list of event numbers and/or the special token 'all'. If a token is prefixed with '-' then the mapping is cleared, otherwise it is set.

After a cold boot, no events are forwarded until/unless mrmrEvrForward is called.

> mrmEvrForward("EVR1") # Prints current mappings
Events forwarded: ...
> mrmEvrForward("EVR1", "-all") # Clear all forward mappings
# Clear all forward mappings except timestamp transmission
> mrmEvrForward("EVR1", "-all, 0x70, 0x71, 0x7A, 0x7D")
# Forward all except 42
> mrmEvrForward("EVR1", "all, -42")
Parameters
idEVR identifier
eventsA string with a comma seperated list of event specifiers

Definition at line 1001 of file drvemSetup.cpp.

1002 {
1003  char *events=events_iocsh ? epicsStrDup(events_iocsh) : 0;
1004 try {
1006  if(!obj)
1007  throw std::runtime_error("Object not found");
1008  EVRMRM *card=dynamic_cast<EVRMRM*>(obj);
1009  if(!card)
1010  throw std::runtime_error("Not a MRM EVR");
1011 
1012  if(!events || strlen(events)==0) {
1013  // Just print current mappings
1014  printf("Events forwarded: ");
1015  for(unsigned int i=1; i<256; i++) {
1016  if(card->specialMapped(i, ActionEvtFwd)) {
1017  printf("%d ", i);
1018  }
1019  }
1020  printf("\n");
1021  free(events);
1022  return;
1023  }
1024 
1025  // update mappings
1026 
1027  const char sep[]=", ";
1028  char *save=0;
1029 
1030  for(char *tok=strtok_r(events, sep, &save);
1031  tok!=NULL;
1032  tok = strtok_r(0, sep, &save)
1033  )
1034  {
1035  if(strcmp(tok, "-all")==0) {
1036  for(unsigned int i=1; i<256; i++)
1037  card->specialSetMap(i, ActionEvtFwd, false);
1038 
1039  } else if(strcmp(tok, "all")==0) {
1040  for(unsigned int i=1; i<256; i++)
1041  card->specialSetMap(i, ActionEvtFwd, true);
1042 
1043  } else {
1044  char *end=0;
1045  long e=strtol(tok, &end, 0);
1046  if(*end || e==LONG_MAX || e==LONG_MIN) {
1047  printf("Unable to parse event spec '%s'\n", tok);
1048  } else if(e>255 || e<-255 || e==0) {
1049  printf("Invalid event %ld\n", e);
1050  } else if(e>0) {
1051  card->specialSetMap(e, ActionEvtFwd, true);
1052  } else if(e<0) {
1053  card->specialSetMap(-e, ActionEvtFwd, false);
1054  }
1055 
1056  }
1057  }
1058 
1059 
1060  free(events);
1061 } catch(std::exception& e) {
1062  printf("Error: %s\n",e.what());
1063  free(events);
1064 }
1065 }
virtual bool specialMapped(epicsUInt32 code, epicsUInt32 func) const OVERRIDE FINAL
Definition: drvem.cpp:505
Modular Register Map Event Receivers.
Definition: drvem.h:94
virtual void specialSetMap(epicsUInt32 code, epicsUInt32 func, bool) OVERRIDE FINAL
Definition: drvem.cpp:524
Base object inspection.
Definition: object.h:378
static Object * getObject(const std::string &name)
Definition: object.cpp:107
#define ActionEvtFwd
Definition: evrRegMap.h:374

◆ mrmEvrInithooks()

void epicsShareFunc mrmEvrInithooks ( initHookState  state)

Definition at line 799 of file drvemSetup.cpp.

800 {
801  epicsUInt8 lvl;
802  switch(state)
803  {
804  case initHookAfterInterruptAccept:
805  // Register hook to disable interrupts on IOC shutdown
806  epicsAtExit(&evrShutdown, NULL);
807  // First enable interrupts for each EVR
808  mrf::Object::visitObjects(&enableIRQ,0);
809  // Then enable all used levels
810  for(lvl=1; lvl<=7; ++lvl)
811  {
812  if (vme_level_mask&(1<<(lvl-1))) {
813  if(devEnableInterruptLevelVME(lvl))
814  {
815  printf("Failed to enable interrupt level %d\n",lvl);
816  return;
817  }
818  }
819 
820  }
821 
822  break;
823  default:
824  break;
825  }
826 }
static void visitObjects(bool(*)(Object *, void *), void *)
Definition: object.cpp:150

◆ mrmEvrLoopback()

void epicsShareFunc mrmEvrLoopback ( const char *  id,
int  rxLoopback,
int  txLoopback 
)

Definition at line 1069 of file drvemSetup.cpp.

1070 {
1071 try {
1073  if(!obj)
1074  throw std::runtime_error("Object not found");
1075  EVRMRM *card=dynamic_cast<EVRMRM*>(obj);
1076  if(!card){
1077  throw std::runtime_error("Not a MRM EVR");
1078  }
1079 
1080  epicsUInt32 control = NAT_READ32(card->base,Control);
1081  control &= ~(Control_txloop|Control_rxloop);
1082  if (rxLoopback) control |= Control_rxloop;
1083  if (txLoopback) control |= Control_txloop;
1084  NAT_WRITE32(card->base,Control, control);
1085 
1086 } catch(std::exception& e) {
1087  printf("Error: %s\n",e.what());
1088 }
1089 }
volatile unsigned char *const base
Definition: drvem.h:237
#define Control_rxloop
Definition: evrRegMap.h:63
Modular Register Map Event Receivers.
Definition: drvem.h:94
Base object inspection.
Definition: object.h:378
static Object * getObject(const std::string &name)
Definition: object.cpp:107
#define Control_txloop
Definition: evrRegMap.h:61
#define NAT_READ32(base, offset)
Definition: mrfCommonIO.h:145
#define NAT_WRITE32(base, offset, value)
Definition: mrfCommonIO.h:148

◆ mrmEvrProbe()

void epicsShareFunc mrmEvrProbe ( const char *  id)

◆ mrmEvrReport()

long epicsShareFunc mrmEvrReport ( int  level)

Definition at line 430 of file drvemSetup.cpp.

431 {
432  printf("=== Begin MRF EVR support ===\n");
433  mrf::Object::visitObjects(&reportCard, (void*)&level);
434  printf("=== End MRF EVR support ===\n");
435  return 0;
436 }
static void visitObjects(bool(*)(Object *, void *), void *)
Definition: object.cpp:150

◆ mrmEvrSetupPCI()

void epicsShareFunc mrmEvrSetupPCI ( const char *  id,
const char *  pcispec,
const char *  mtca_evr_model 
)

Definition at line 499 of file drvemSetup.cpp.

500 {
501 try {
502  bus_configuration bus;
503 
504  bus.busType = busType_pci;
505 
506  if(mrf::Object::getObject(id)){
507  printf("Object ID %s already in use\n",id);
508  return;
509  }
510 
511  /* Linux only
512  * kernel driver interface version.
513  * 0 - Broken
514  * 1 - Use of irqcontrol callback to avoid races for plx pci bridges
515  * 2 - Use of new PCI master enable register to avoid races for soft pci bridges
516  */
517  int kifacever = -1;
518  if(checkUIOVersion(1,2,&kifacever))
519  return;
520 
521  const epicsPCIDevice *cur=0;
522 
523  if( devPCIFindSpec(mrmevrs, pcispec, &cur,0) ){
524  printf("PCI Device not found on %s\n",
525  pcispec);
526  return;
527  }
528 
529  printf("Device %s %x:%x.%x slot=%s\n",id,cur->bus,cur->device,cur->function,cur->slot);
530  printf("Using IRQ %u\n",cur->irq);
531 
532  bus.pci.dev = cur;
533 
534  const EVRMRM::Config *conf = NULL;
535  switch(cur->id.sub_device) {
536  case PCI_DEVICE_ID_MRF_PMCEVR_230: conf = &pmc_evr_230; break;
537  case PCI_DEVICE_ID_MRF_PXIEVR_230: conf = &cpci_evr_230; break;
538  case PCI_DEVICE_ID_MRF_EVRTG_300: conf = &cpci_evrtg_300; break;
539  case PCI_DEVICE_ID_MRF_CPCIEVR300: conf = &cpci_evr_300; break;
541  if (mtca_evr_model == NULL)
542  {
543  // if no EVR type is provided, we assume mtca_evr_300 generic as this was the default beforehand
544  mtca_evr_model = "default";
545  conf = &mtca_evr_300;
546  } else if (strcmp(mtca_evr_model, "UNIV") == 0) {
547  printf("Config for EVR FP UNIV model (mTCA-EVR-300U).\n");
548  conf = &mtca_evr_300u;
549  } else if (strcmp(mtca_evr_model, "IFB") == 0) {
550  printf("Config for EVR FP IFB model (mTCA-EVR-300IFB - obsolete).\n");
551  conf = &mtca_evr_300ifb;
552  } else if (strcmp(mtca_evr_model, "RF") == 0) {
553  printf("Config for EVR FP RF model (mTCA-EVR-300RF).\n");
554  conf = &mtca_evr_300rf;
555  } else {
556  printf("Error: mtca_evr_model arg (%s), needs no param (default) or 'UNIV' or 'RF' or 'IFB'.\n", mtca_evr_model);
557  return;
558  }
559  break;
560  case PCI_DEVICE_ID_MRF_EVRTG_300E: // aka PCI_SUBDEVICE_ID_PCIE_EVR_300
561  switch (cur->id.device) {
562  case PCI_DEVICE_ID_EC_30: conf = &cpci_evrtg_300; break;
563  case PCI_DEVICE_ID_XILINX_DEV: conf = &pcie_evr_300; break;
564  }
565  break;
566  }
567 
568  if(!conf) {
569  printf("Unknown PCI EVR variant, making assumptions...\n");
570  conf = &cpci_evr_unknown;
571  }
572 
573  volatile epicsUInt8 *plx = 0, *evr = 0;
574  epicsUInt32 evrlen = 0;
575 
576  if(devPCIToLocalAddr(cur,0,(volatile void**)(void *)&evr,DEVLIB_MAP_UIO1TO1))
577  {
578  printf("PCI error: Failed to map BAR 0\n");
579  return;
580  }
581  if(!evr){
582  printf("PCI error: BAR 0 mapped to zero? (%08lx)\n", (unsigned long)evr);
583  return;
584  }
585  if( devPCIBarLen(cur,0,&evrlen) ) {
586  printf("PCI error: Can't find BAR #0 length\n");
587  return;
588  }
589 
590  switch(cur->id.device) {
593  plx = evr;
594 
595  if(devPCIToLocalAddr(cur,2,(volatile void**)(void *)&evr,DEVLIB_MAP_UIO1TO1))
596  {
597  printf("PCI error: Failed to map BAR 2\n");
598  return;
599  }
600  if(!evr){
601  printf("PCI error: BAR 2 mapped to zero? (%08lx)\n", (unsigned long)evr);
602  return;
603  }
604  if( devPCIBarLen(cur,0,&evrlen) ) {
605  printf("PCI error: Can't find BAR #0 length\n");
606  return;
607  }
608  }
609 
610  // handle various PCI to local bus bridges
611  switch(cur->id.device) {
613  printf("Setup PLX PCI 9030\n");
614  /* Use the PLX device on the EVR to swap access on
615  * little endian systems so we don't have no worry about
616  * byte order :)
617  */
618 #if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG
619  BITSET(LE,32, plx, LAS0BRD, LAS0BRD_ENDIAN);
620 #elif EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE
621  BITCLR(LE,32, plx, LAS0BRD, LAS0BRD_ENDIAN);
622 #endif
623 
624  // Disable interrupts on device
625 
626  NAT_WRITE32(evr, IRQEnable, 0);
627 
628 #ifndef __linux__
629  /* Enable active high interrupt1 through the PLX to the PCI bus.
630  */
634 #endif
635  break;
636 
638 #if EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG
639  BITSET(LE,8, plx, BIGEND9056, BIGEND9056_BIG);
640 #elif EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE
641  BITCLR(LE,8, plx, BIGEND9056, BIGEND9056_BIG);
642 #endif
643 
644  // Disable interrupts on device
645 
646  NAT_WRITE32(evr, IRQEnable, 0);
647 
648 #ifndef __linux__
650 #endif
651  break;
652 
653  case PCI_DEVICE_ID_EC_30:
656  /* the endianness the 300 series devices w/o PLX bridge
657  * is a little tricky to setup. byte order swapping is controlled
658  * through the EVR's Control register and access to this register
659  * is subject to byte order swapping...
660  */
661 
662  // Disable EVR and set byte order to big endian
663  NAT_WRITE32(evr, Control, 0);
664  // Enable byte order swapping if necessary
665 #if EPICS_BYTE_ORDER == EPICS_ENDIAN_LITTLE
666  BE_WRITE32(evr, Control, 0x02000000);
667 #endif
668 
669  // Disable interrupts on device
670  NAT_WRITE32(evr, IRQEnable, 0);
671 
672 #ifndef __linux__
674 #endif
675  break;
676  default:
677  printf("Unknown PCI bridge %04x\n", cur->id.device);
678  return;
679  }
680 
681  checkVersion(evr, 3, 6);
682 
683  // Acknowledge missed interrupts
684  //TODO: This avoids a spurious FIFO Full
685  NAT_WRITE32(evr, IRQFlag, NAT_READ32(evr, IRQFlag));
686 
687  // Install ISR
688 
689  EVRMRM *receiver=new EVRMRM(id,bus,conf,evr,evrlen);
690 
691  void *arg=receiver;
692 #ifdef __linux__
693  receiver->isrLinuxPvt = (void*)cur;
694 #endif
695 
696  if(devPCIConnectInterrupt(cur, &EVRMRM::isr_pci, arg, 0)){
697  printf("Failed to install ISR\n");
698  delete receiver;
699  return;
700  }else{
701  // Interrupts will be enabled during iocInit()
702  }
703 
704 
705 #ifndef __linux__
706  if(receiver->version()>=MRFVersion(0, 0xa)) {
707  // RTOS doesn't need this, so always enable
708  WRITE32(evr, PCI_MIE, EVG_MIE_ENABLE);
709  }
710 #else
711  if(receiver->version()>=MRFVersion(0, 0xa) && kifacever>=2) {
712  // PCI master enable supported by firmware and kernel module.
713  // the kernel will set this bit when devPCIEnableInterrupt() is called
714  } else if(cur->id.device==PCI_DEVICE_ID_PLX_9030 ||
715  cur->id.device==PCI_DEVICE_ID_PLX_9056) {
716  // PLX based devices don't need special handling
717  WRITE32(evr, PCI_MIE, EVG_MIE_ENABLE);
718  } else if(receiver->version()<MRFVersion(0, 0xa)) {
719  // old firmware and (maybe) old kernel module.
720  // this will still work, so just complain
721  printf("Warning: this configuration of FW and SW is known to have race conditions in interrupt handling.\n"
722  " Please consider upgrading to FW version 0xA.\n");
723  if(kifacever<2)
724  printf(" Also upgrade the linux kernel module to interface version 2.");
725  } else if(receiver->version()>=MRFVersion(0, 0xa) && kifacever<2) {
726  // New firmware w/ old kernel module, this won't work
727  throw std::runtime_error("FW version 0xA for this device requires a linux kernel module w/ interface version 2");
728  } else {
729  throw std::logic_error("logic error in FW/kernel module compatibility check.");
730  }
731 
732  /* ask the kernel module to enable interrupts */
733  printf("Enabling interrupts\n");
734  if(devPCIEnableInterrupt(cur)) {
735  printf("Failed to enable interrupt\n");
736  delete receiver;
737  return;
738  }
739 #endif
740 
741 } catch(std::exception& e) {
742  printf("Error: %s\n",e.what());
743 }
744  errlogFlush();
745 }
enum busType busType
#define BITSET32(base, offset, mask)
Definition: mrfCommonIO.h:124
#define BITCLR(ord, len, base, offset, mask)
Definition: mrfBitOps.h:26
#define LE_WRITE16(base, offset, value)
Definition: mrfCommonIO.h:199
#define IRQ_PCIee
Definition: mrf.h:119
#define PCI_DEVICE_ID_MRF_PMCEVR_230
Definition: mrmpci.h:33
#define IRQEnable
Definition: mrf.h:115
#define PCI_DEVICE_ID_MRF_EVRMTCA300
Definition: uio_mrf.c:74
#define LAS0BRD
Definition: mrf.h:41
static void isr_pci(void *)
Definition: drvem.cpp:1133
#define BE_WRITE32(base, offset, value)
Definition: mrfCommonIO.h:170
Modular Register Map Event Receivers.
Definition: drvem.h:94
#define PCI_DEVICE_ID_MRF_PXIEVR_230
Definition: mrmpci.h:34
#define BIGEND9056
Definition: mrf.h:74
static Object * getObject(const std::string &name)
Definition: object.cpp:107
#define BIGEND9056_BIG
Definition: plx9056.h:21
#define PCI_DEVICE_ID_XILINX_DEV
Definition: uio_mrf.c:48
#define PCI_DEVICE_ID_EC_30
Definition: uio_mrf.c:46
#define NAT_READ32(base, offset)
Definition: mrfCommonIO.h:145
#define IRQFlag
Definition: mrf.h:106
struct configuration_pci pci
const epicsPCIDevice * dev
#define LAS0BRD_ENDIAN
Definition: plx9030.h:24
#define INTCSR9056
Definition: mrf.h:77
#define PCI_DEVICE_ID_MRF_EVRTG_300E
Definition: mrmpci.h:36
#define PCI_DEVICE_ID_MRF_EVRTG_300
Definition: mrmpci.h:35
#define INTCSR_INT1_Polarity
Definition: plx9030.h:29
#define EVG_MIE_ENABLE
Definition: evgRegMap.h:64
#define NAT_WRITE32(base, offset, value)
Definition: mrfCommonIO.h:148
virtual MRFVersion version() const OVERRIDE FINAL
Firmware Version.
Definition: drvem.cpp:415
#define INTCSR
Definition: mrf.h:46
#define BITSET(ord, len, base, offset, mask)
Definition: mrfBitOps.h:21
void checkVersion(volatile epicsUInt8 *base, const MRFVersion &required, const MRFVersion &recommended)
Definition: evgInit.cpp:165
#define WRITE32(base, offset, value)
Definition: mrfCommonIO.h:119
#define PCI_DEVICE_ID_PLX_9056
Definition: uio_mrf.c:51
#define INTCSR9056_LCL_Enable
Definition: plx9056.h:25
#define PCI_DEVICE_ID_PLX_9030
Definition: uio_mrf.c:50
#define INTCSR_INT1_Enable
Definition: plx9030.h:28
#define INTCSR_PCI_Enable
Definition: plx9030.h:34
#define INTCSR9056_PCI_Enable
Definition: plx9056.h:24
#define PCI_DEVICE_ID_MRF_CPCIEVR300
Definition: mrmpci.h:50

◆ mrmEvrSetupVME()

void epicsShareFunc mrmEvrSetupVME ( const char *  id,
int  slot,
int  base,
int  level,
int  vector 
)

Definition at line 830 of file drvemSetup.cpp.

831 {
832 try {
833  bus_configuration bus;
834  const EVRMRM::Config *conf = &vme_evrrf_230;
835 
836  bus.busType = busType_vme;
837  bus.vme.slot = slot;
838  bus.vme.address = base;
839  bus.vme.irqLevel = level;
840  bus.vme.irqVector = vector;
841 
842  if(mrf::Object::getObject(id)){
843  printf("ID %s already in use\n",id);
844  return;
845  }
846 
847  struct VMECSRID info;
848 
849  volatile unsigned char* csr=devCSRTestSlot(vmeevrs,slot,&info);
850  if(!csr){
851  printf("No EVR in slot %d\n",slot);
852  return;
853  }
854 
855  printf("Setting up EVR in VME Slot %d\n",slot);
856 
857  printf("Found vendor: %08x board: %08x rev.: %08x\n",
858  info.vendor, info.board, info.revision);
859 
860  // Set base address
861 
862  /* Use function 0 for 16-bit addressing (length 0x00800 bytes)
863  * and function 1 for 24-bit addressing (length 0x10000 bytes)
864  * and function 2 for 32-bit addressing (length 0x40000 bytes)
865  *
866  * All expose the same registers, but not all registers are
867  * visible through functions 0 or 1.
868  */
869 
870  CSRSetBase(csr, 2, base, VME_AM_EXT_SUP_DATA);
871 
872  {
873  epicsUInt32 temp=CSRRead32((csr) + CSR_FN_ADER(2));
874 
875  if(temp != CSRADER((epicsUInt32)base,VME_AM_EXT_SUP_DATA)) {
876  printf("Failed to set CSR Base address in ADER2. Check VME bus and card firmware version.\n");
877  return;
878  }
879  }
880 
881  volatile unsigned char* evr;
882  char *Description = allocSNPrintf(40, "EVR-%d '%s' slot %d",
883  info.board & MRF_BID_SERIES_MASK,
884  id, slot);
885 
886  if(devRegisterAddress(Description, atVMEA32, base, EVR_REGMAP_SIZE, (volatile void**)(void *)&evr))
887  {
888  printf("Failed to map address %08x\n",base);
889  return;
890  }
891 
892  epicsUInt32 junk;
893  if(devReadProbe(sizeof(junk), (volatile void*)(evr+U32_FWVersion), (void*)&junk)) {
894  printf("Failed to read from MRM registers (but could read CSR registers)\n");
895  return;
896  }
897 
898  checkVersion(evr, 4, 5);
899 
900  // Read offset from start of CSR to start of user (card specific) CSR.
901  size_t user_offset=CSRRead24(csr+CR_BEG_UCSR);
902  // Currently that value read from the UCSR pointer is
903  // actually little endian.
904  user_offset= (( user_offset & 0x00ff0000 ) >> 16 ) |
905  (( user_offset & 0x0000ff00 ) ) |
906  (( user_offset & 0x000000ff ) << 16 );
907  volatile unsigned char* user_csr=csr+user_offset;
908 
909  NAT_WRITE32(evr, IRQEnable, 0); // Disable interrupts
910 
911  EVRMRM *receiver=new EVRMRM(id, bus, conf, evr, EVR_REGMAP_SIZE);
912 
913  if(level>0 && vector>=0) {
914  CSRWrite8(user_csr+UCSR_IRQ_LEVEL, level&0x7);
915  CSRWrite8(user_csr+UCSR_IRQ_VECTOR, vector&0xff);
916 
917  printf("Using IRQ %d:%2d\n",
918  CSRRead8(user_csr+UCSR_IRQ_LEVEL),
919  CSRRead8(user_csr+UCSR_IRQ_VECTOR)
920  );
921 
922  // Acknowledge missed interrupts
923  //TODO: This avoids a spurious FIFO Full
924  NAT_WRITE32(evr, IRQFlag, NAT_READ32(evr, IRQFlag));
925 
926  level&=0x7;
927  // VME IRQ level will be enabled later during iocInit()
928  vme_level_mask|=1<<(level-1);
929 
930  if(devConnectInterruptVME(vector&0xff, &EVRMRM::isr_vme, receiver))
931  {
932  printf("Failed to connection VME IRQ %d\n",vector&0xff);
933  delete receiver;
934  return;
935  }
936 
937  // Interrupts will be enabled during iocInit()
938  }
939 
940 } catch(std::exception& e) {
941  printf("Error: %s\n",e.what());
942 }
943  errlogFlush();
944 }
struct configuration_vme vme
enum busType busType
#define U32_FWVersion
Definition: evrRegMap.h:141
#define IRQEnable
Definition: mrf.h:115
static void isr_vme(void *)
Definition: drvem.cpp:1147
Modular Register Map Event Receivers.
Definition: drvem.h:94
#define UCSR_IRQ_LEVEL
Definition: mrfcsr.h:59
#define MRF_BID_SERIES_MASK
Definition: mrfcsr.h:31
char * allocSNPrintf(size_t N, const char *fmt,...)
Definition: mrfCommon.cpp:58
static Object * getObject(const std::string &name)
Definition: object.cpp:107
#define NAT_READ32(base, offset)
Definition: mrfCommonIO.h:145
#define IRQFlag
Definition: mrf.h:106
#define EVR_REGMAP_SIZE
Definition: evrRegMap.h:389
#define NAT_WRITE32(base, offset, value)
Definition: mrfCommonIO.h:148
#define UCSR_IRQ_VECTOR
Definition: mrfcsr.h:60
void checkVersion(volatile epicsUInt8 *base, const MRFVersion &required, const MRFVersion &recommended)
Definition: evgInit.cpp:165

Variable Documentation

◆ evrmrmVerb

epicsShareExtern int evrmrmVerb

Extra noise control.

Controls level of extra diagnositic output from the EVR MRM device support. Error messages are always printed.

0 - No output 1 - Basic Startup 2 - Extended startup some "write" 3 - All "write" (output record processing) 4 - Some "read" (input record processing) and IRQ

Definition at line 34 of file drvemIocsh.h.