Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals | Related Pages

RCCVmeInterface.cxx

00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 // 20/02/2002  V 1.0 PM - First implementation
00009 //  4/04/2002  V 1.1 PM - Block transfer not working, Interrupt 
00010 //                        Handling not implemented
00011 // 18/04/2002  V 1.2 PM - Block transfer and interrupts ok. Bus error
00012 //                        handling ok. Other ecxeptions still to be
00013 //                        implemented           
00014 // 22/04/2002  V 1.3 PM - New methods for blocking and resuming 
00015 //                        interrupt notification
00016 //                        Support for RORA interrupts on level 6
00017 //                        New method for passing an int to soft
00018 //                        interrupts.           
00019 // 13/08/2002  V 1.4 PM - Modifications for RCC v3
00020 // 19/02/2004  V 1.5 PM - Safe single word R/W methods added            
00021 // 19/07/2004  V 1.6 JL - Throw VmeException if VME_Open fails
00022 //
00023 
00024 #include <signal.h>
00025 #include <sys/types.h>
00026 
00027 #include "RCCVmeInterface.h"
00028 #include "cmem_rcc/cmem_rcc.h"
00029 
00030 using namespace SctPixelRod;
00031 
00032 long RCCVmeInterface::m_busErrors = 0;
00033 int  RCCVmeInterface::m_irqId[8] = { -1, -1, -1, -1, -1, -1, -1, -1};       
00034 sigset_t RCCVmeInterface::m_sigMask;
00035         
00036 long RCCVmeInterface::m_interruptData = 0;
00037 RCCVmeInterface* RCCVmeInterface::m_if = NULL;
00038 unsigned char  RCCVmeInterface::m_softVectMask[256];                      
00039 VmeInterruptHandler*  RCCVmeInterface::m_hardIH[8][256][10];   
00040 VmeInterruptHandler*  RCCVmeInterface::m_softIH[32][10];  
00041 void RCCVmeInterface::m_exitHandler(int signum) {
00042   delete m_if; 
00043   exit(0);
00044 }
00045 
00046 void RCCVmeInterface::m_busErrorHandler(int signum) {
00047   RCCVmeInterface::m_busErrors++; 
00048 }
00049 
00050 void RCCVmeInterface::m_interruptHandler(int signum) {
00051   int is, smask;
00052   unsigned int i;
00053   static VME_InterruptInfo_t info[8];
00054   
00055   // Get interrupt info  
00056   int level = SIGRTMAX - signum;
00057   VME_InterruptInfoGet(m_irqId[level],&info[level]);
00058   int vec = info[level].vector;
00059 
00060 
00061   // Execute hard handlers
00062   m_softVectMask[vec] = 0;
00063   m_if->m_interruptData = 0;
00064   for (i=0; i<10; i++) {
00065     if (m_hardIH[level][vec][i] != 0) {
00066       if (m_hardIH[level][vec][i]->getActive()) {
00067         m_hardIH[level][vec][i]->interruptHandler(vec, 0, info[level].multiple);
00068       }
00069     }
00070   }
00071   
00072   // Execute soft handlers
00073   smask = m_softVectMask[vec];
00074   for (is=0; is<32; is++) {
00075     if ((smask & (1 << is)) != 0) { 
00076       for (i=0; i<10; i++) {
00077         if (m_softIH[is][i] != 0) {
00078       if (m_softIH[is][i]->getActive()) {
00079         m_softIH[is][i]->interruptHandler(vec, is, info[level].multiple);
00080       }
00081     }
00082       }
00083     }
00084   }
00085 
00086   // Re-enable interrupts
00087   if (info[level].type == VME_INT_RORA) {
00088     VME_InterruptReenable(m_irqId[level]);
00089   }
00090 }
00091 
00092 RCCVmeInterface::RCCVmeInterface() {
00093   int ret;
00094   int i,j,k;
00095 
00096   // Init status variable
00097   m_ok = false;
00098 
00099   // Open the package
00100   m_lastErrcode = VME_Open();
00101 
00102   if (m_lastErrcode != 0)
00103       throw VmeException(VmeException::INIT_ERROR, m_lastErrcode);
00104 
00105   // Pre-allocate a DMA buffer
00106   ret = CMEM_Open();
00107   ret = CMEM_SegmentAllocate(0x10000, "VmeInterface DMA", &m_dmaBuf); 
00108   if (ret) {
00109     m_dmaBufSize = 0;
00110   } else {
00111     m_dmaBufSize = 0x10000;
00112   }
00113   // Install the bus error handler
00114   struct sigaction sa;
00115   sigemptyset(&sa.sa_mask); 
00116   sa.sa_flags = 0;
00117   sa.sa_handler = m_busErrorHandler; 
00118   ret = sigaction(SIGBUS, &sa, NULL);
00119   m_lastErrcode = VME_BusErrorRegisterSignal(SIGBUS);
00120   m_lastErrcode = VME_BusErrorInfoGet(&m_busErrInfo);
00121   // Install the global interrupt handler
00122   sigemptyset(&sa.sa_mask); 
00123   sa.sa_flags = 0;
00124   sa.sa_handler = m_interruptHandler; 
00125   for (i=0; i<8; i++) sigaction(SIGRTMAX-i, &sa, NULL);
00126   // Install the exit handler
00127   sigemptyset(&sa.sa_mask); 
00128   sa.sa_flags = 0;
00129   sa.sa_handler = m_exitHandler; 
00130   ret = sigaction(SIGTERM, &sa, NULL);
00131   ret = sigaction(SIGINT, &sa, NULL);
00132   // Pepare the mask for blocking interrupt handlers
00133   sigemptyset(&m_sigMask);
00134   for (i=0; i<8; i++) sigaddset(&m_sigMask, SIGRTMAX-i);
00135   // Clear the list of interrupts
00136   for (i=0; i<8; i++) m_irq[i].number_of_items = 0;
00137   for (i=0; i<10; i++) {
00138     for (k=0; k<256; k++) {
00139       for (j=0; j<8; j++) {
00140     m_hardIH[j][k][i] = 0;
00141       }
00142     } 
00143     for (k=0; k<32; k++) {
00144       m_softIH[k][i] = 0;
00145     }
00146   }
00147   // Set the static pointer to this object
00148   m_if = this;
00149   // Set status variable to ok
00150   m_ok = true;
00151 };
00152 
00153 
00154 RCCVmeInterface::~RCCVmeInterface() {
00155   std::cerr << "Deleting VmeInterface..." << std::endl;
00156   // Release the DMA buffer
00157   if (m_dmaBufSize != 0) {
00158     std::cout << "  Releasing DMA buffer" << std::endl;
00159     CMEM_SegmentFree(m_dmaBuf);
00160   }
00161   CMEM_Close();
00162   // Unlink the interrupts
00163   int i;
00164   for (i=0; i<8; i++) {
00165     if (m_irq[i].number_of_items > 0) {
00166       std::cout << "  Unlinking interrupt handlers for level " << i << std::endl;
00167       m_lastErrcode = VME_InterruptRegisterSignal(m_irqId[i], 0);
00168       m_lastErrcode = VME_InterruptUnlink(m_irqId[i]);
00169       m_irq[i].number_of_items = 0;
00170     }
00171   }
00172   // Remove existing port mappings
00173   unsigned int ip;
00174   for (ip=0; ip<m_ports.size(); ip++) {
00175     if (m_ports[ip] != NULL) {
00176       std::cout << "  Unmapping port " << ip  << std::endl;
00177       VME_MasterUnmap(m_ports[ip]->getHandle());
00178       m_ports[ip] = NULL;
00179     }
00180   }
00181   // Close the package
00182   VME_Close();
00183   m_ok = false;
00184 };
00185 
00186 void RCCVmeInterface::declareInterruptHandler(VmeInterruptHandler &handler) {
00187   unsigned char vect = handler.getInterruptVector();
00188   unsigned char softvec = handler.getInterruptSoftVect();
00189   unsigned int level = handler.getInterruptLevel();
00190   if (softvec == 0) {
00191     if (level <= 0 || level > 7) return;
00192     // Hard IH definition
00193     unsigned int i,nh=0;
00194     for (i=0; i<10; i++) {
00195       if (&handler == m_hardIH[level][vect][i]) return;
00196       if (m_hardIH[level][vect][i] != 0) nh++;
00197     }
00198     for (i=0; i<10; i++) {
00199       if (m_hardIH[level][vect][i] == 0) {
00200     m_hardIH[level][vect][i] = &handler; 
00201         nh++;
00202     break;
00203       }
00204     }
00205     if (nh == 1) {
00206       // Set up the glodal handler
00207       if (m_irq[level].number_of_items > 0) {      
00208         m_lastErrcode = VME_InterruptRegisterSignal(m_irqId[level], 0);
00209         m_lastErrcode = VME_InterruptUnlink(m_irqId[level]);
00210       }
00211       m_irq[level].list_of_items[m_irq[level].number_of_items].vector = vect;
00212       m_irq[level].list_of_items[m_irq[level].number_of_items].level = level;
00213       if (level == 6) {
00214         m_irq[level].list_of_items[m_irq[level].number_of_items].type = VME_INT_RORA;
00215       } else {
00216         m_irq[level].list_of_items[m_irq[level].number_of_items].type = VME_INT_ROAK;
00217       }
00218       m_irq[level].number_of_items++;
00219       m_lastErrcode = VME_InterruptLink(&m_irq[level], &m_irqId[level]);
00220       m_lastErrcode = VME_InterruptRegisterSignal(m_irqId[level], SIGRTMAX-level);      
00221     }
00222   } else if (softvec > 0 && softvec <= 32) {
00223     // Soft IH definition
00224     unsigned int i;
00225     for (i=0; i<10; i++) {
00226       if (&handler == m_softIH[softvec-1][i]) return;
00227     }
00228     for (i=0; i<10; i++) {
00229       if (m_softIH[softvec-1][i] == 0) {
00230     m_softIH[softvec-1][i] = &handler; 
00231     break;
00232       }
00233     }
00234   }
00235 }
00236 
00237 void RCCVmeInterface::cleanInterruptHandlers() {
00238   // Unlink the global handler
00239   int i,j,k;
00240   for (i=0; i<8; i++) {
00241     if (m_irq[i].number_of_items > 0) {      
00242       m_lastErrcode = VME_InterruptUnlink(m_irqId[i]);
00243       m_lastErrcode = VME_InterruptRegisterSignal(m_irqId[i], 0);
00244       m_irq[i].number_of_items = 0;
00245     }
00246   }
00247   for (i=0; i<10; i++) {
00248     for (k=0; k<256; k++) {
00249       for (j=0; j<8; j++) {
00250     m_hardIH[j][k][i] = 0;
00251       }
00252     } 
00253     for (k=0; k<32; k++) {
00254       m_softIH[k][i] = 0;
00255     }
00256   }
00257 }
00258 
00259 void RCCVmeInterface::removeInterruptHandler(VmeInterruptHandler &handler) {
00260   char vect = handler.getInterruptVector();
00261   char softvec = handler.getInterruptSoftVect();
00262   int level = handler.getInterruptLevel();
00263   if (softvec == 0) {   
00264     int i, nh=0;
00265     // Basic IH cancellation
00266     for (i=0; i<10; i++) {
00267       if (&handler == m_hardIH[level][vect][i]) {      
00268         m_hardIH[level][vect][i] = 0;
00269         break;
00270       }
00271       for (i=0; i<10; i++) {
00272         if (m_hardIH[level][vect][i] !=0) nh++;
00273       }
00274     }
00275     if (nh == 0) {
00276       // Check if vect has installed handlers
00277       int iv;
00278       bool found = false;
00279       for (iv=0; iv<m_irq[level].number_of_items; iv++) {
00280         if (found) m_irq[level].list_of_items[iv-1] = m_irq[level].list_of_items[iv];
00281         if (vect == m_irq[level].list_of_items[iv].vector) found = true;
00282       }
00283       if (found) {
00284         // Unlink the global handler
00285         if (m_irq[level].number_of_items > 0) {      
00286           m_lastErrcode = VME_InterruptUnlink(m_irqId[level]);
00287           m_lastErrcode = VME_InterruptRegisterSignal(m_irqId[level], 0);
00288         }
00289         
00290         if (--m_irq[level].number_of_items == 0) {
00291           m_irqId[level] = -1;
00292         } else {     
00293           m_lastErrcode = VME_InterruptLink(&m_irq[level], &m_irqId[level]);
00294           m_lastErrcode = VME_InterruptRegisterSignal(m_irqId[level], 0);
00295     }
00296       }
00297     }
00298   } else if (softvec > 0 && softvec <= 32) {
00299     int i;
00300     // Soft IH cancellation
00301     for (i=0; i<10; i++) {
00302       if (&handler == m_softIH[softvec-1][i]) {
00303         m_softIH[softvec-1][i]=0;
00304         return;
00305       }
00306     }
00307   }  
00308 }
00309 
00310 void RCCVmeInterface::reEnableInterrupt() {
00311   int i;
00312   for (i=0; i<8; i++) VME_InterruptReenable(m_irqId[i]);
00313 }
00314  
00315 void RCCVmeInterface::blockInterruptNotification() {
00316   pthread_sigmask(SIG_BLOCK, &m_sigMask, NULL);
00317 } 
00318 
00319 void RCCVmeInterface::resumeInterruptNotification() {
00320   pthread_sigmask(SIG_UNBLOCK, &m_sigMask, NULL);
00321 }
00322 
00323 unsigned char RCCVmeInterface::read8  (const unsigned long handle, const unsigned long offset) {
00324   u_char ldata;       
00325   VME_ReadFastUChar(handle ,offset, &ldata);
00326   busErrorReport(handle);
00327   return ldata;
00328 }  
00329 
00330 unsigned char RCCVmeInterface::readS8 (const unsigned long handle, const unsigned long offset) {
00331   u_char ldata;
00332   VME_ErrorCode_t ret;       
00333   ret = VME_ReadSafeUChar(handle ,offset, &ldata);
00334   if (ret != VME_SUCCESS) throw VmeException(VmeException::BUS_ERROR, VME_BUSERROR); 
00335   return ldata;
00336 }
00337 
00338 unsigned short RCCVmeInterface::read16 (const unsigned long handle, const unsigned long offset) {
00339   u_short ldata;       
00340   VME_ReadFastUShort(handle ,offset, &ldata);
00341   busErrorReport(handle);
00342   return ldata;
00343 }
00344 
00345 unsigned short RCCVmeInterface::readS16 (const unsigned long handle, const unsigned long offset) {
00346   u_short ldata;
00347   VME_ErrorCode_t ret;       
00348   ret = VME_ReadSafeUShort(handle ,offset, &ldata);
00349   if (ret != VME_SUCCESS) throw VmeException(VmeException::BUS_ERROR, VME_BUSERROR); 
00350   return ldata;
00351 }
00352 
00353 unsigned long RCCVmeInterface::read32 (const unsigned long handle, const unsigned long offset) {
00354   u_int ldata;       
00355   VME_ReadFastUInt(handle ,offset, &ldata);
00356   busErrorReport(handle);
00357   return ldata;
00358 }
00359 
00360 unsigned long RCCVmeInterface::readS32 (const unsigned long handle, const unsigned long offset) {
00361   u_int ldata;
00362   VME_ErrorCode_t ret;       
00363   ret = VME_ReadSafeUInt(handle ,offset, &ldata);
00364   if (ret != VME_SUCCESS) throw VmeException(VmeException::BUS_ERROR, VME_BUSERROR); 
00365   return ldata;
00366 }
00367 
00368 void RCCVmeInterface::write8 (const unsigned long handle, const unsigned long offset, const unsigned char value) {
00369   VME_WriteFastUChar(handle ,offset, value);
00370   busErrorReport(handle);
00371 }  
00372 
00373 void RCCVmeInterface::writeS8 (const unsigned long handle, const unsigned long offset, const unsigned char value) {
00374   VME_ErrorCode_t ret;       
00375   ret = VME_WriteSafeUChar(handle ,offset, value);
00376   if (ret != VME_SUCCESS) throw VmeException(VmeException::BUS_ERROR, VME_BUSERROR); 
00377 }  
00378 
00379 void RCCVmeInterface::write16(const unsigned long handle, const unsigned long offset, const unsigned short value) {
00380   VME_WriteFastUShort(handle ,offset, value);
00381   busErrorReport(handle);
00382 }    
00383 
00384 void RCCVmeInterface::writeS16 (const unsigned long handle, const unsigned long offset, const unsigned short value) {
00385   VME_ErrorCode_t ret;       
00386   ret = VME_WriteSafeUShort(handle ,offset, value);
00387   if (ret != VME_SUCCESS) throw VmeException(VmeException::BUS_ERROR, VME_BUSERROR); 
00388 }  
00389 
00390 void RCCVmeInterface::write32(const unsigned long handle, const unsigned long offset, const unsigned long value) {
00391   VME_WriteFastUInt(handle ,offset, value);
00392   busErrorReport(handle);
00393 }   
00394 
00395 void RCCVmeInterface::writeS32 (const unsigned long handle, const unsigned long offset, const unsigned long value) {
00396   VME_ErrorCode_t ret;       
00397   ret = VME_WriteSafeUInt(handle ,offset, value);
00398   if (ret != VME_SUCCESS) throw VmeException(VmeException::BUS_ERROR, VME_BUSERROR); 
00399 }  
00400 
00401 void RCCVmeInterface::blockRead32 (VmePort &port, const unsigned long offset, unsigned long *buf, const long len) {
00402   if (port.getAddrMod() == A16) {
00403     // Block moving not implemented in A16;
00404     return;
00405   }
00406   m_btList.number_of_items = 1;
00407   m_btList.list_of_items[0].vmebus_address = port.getBaseAddress()+offset;
00408   m_btList.list_of_items[0].size_requested = len;
00409   m_btList.list_of_items[0].control_word = VME_DMA_D32R | m_RCCAddrMod(port.getAddrMod());
00410   m_blockTransferRead(buf);      
00411   busErrorReport(port);
00412 } 
00413 
00414 void RCCVmeInterface::blockRead64 (VmePort &port, const unsigned long offset, unsigned long *buf, const long len) {
00415   if (port.getAddrMod() == A16) {
00416     // Block moving not implemented in A16;
00417     return;
00418   }
00419   m_btList.number_of_items = 1;
00420   m_btList.list_of_items[0].vmebus_address = port.getBaseAddress()+offset;
00421   m_btList.list_of_items[0].size_requested = len;
00422   m_btList.list_of_items[0].control_word = VME_DMA_D64R | m_RCCAddrMod(port.getAddrMod());
00423   m_blockTransferRead(buf);      
00424   busErrorReport(port);
00425 }
00426 
00427 void RCCVmeInterface::blockWrite32(VmePort &port, const unsigned long offset, const unsigned long *buf, const long len) {
00428   if (port.getAddrMod() == A16) {
00429     // Block moving not implemented in A16;
00430     return;
00431   }
00432   m_btList.number_of_items = 1;
00433   m_btList.list_of_items[0].vmebus_address = port.getBaseAddress()+offset;
00434   m_btList.list_of_items[0].size_requested = len;
00435   m_btList.list_of_items[0].control_word = VME_DMA_D32W | m_RCCAddrMod(port.getAddrMod());
00436   m_blockTransferWrite(buf);      
00437   busErrorReport(port);
00438 }  
00439 
00440 void RCCVmeInterface::blockWrite64(VmePort &port, const unsigned long offset, const unsigned long *buf, const long len) {
00441   if (port.getAddrMod() == A16) {
00442     // Block moving not implemented in A16;
00443     return;
00444   }
00445   m_btList.number_of_items = 1;
00446   m_btList.list_of_items[0].vmebus_address = port.getBaseAddress()+offset;
00447   m_btList.list_of_items[0].size_requested = len;
00448   m_btList.list_of_items[0].control_word = VME_DMA_D64W | m_RCCAddrMod(port.getAddrMod());
00449   m_blockTransferWrite(buf);      
00450   busErrorReport(port);
00451 }   
00452 
00453 void RCCVmeInterface::m_blockTransferRead(unsigned long *buf) {
00454   unsigned long ret;
00455 
00456   long vmebusAddr = m_btList.list_of_items[0].vmebus_address;
00457   if (vmebusAddr%4 != 0) throw VmeException(VmeException::MAP_ERROR, VMEADD_MISALIGNED); 
00458   
00459   // Check if the dma buffer needs to be enlarged
00460   long size = m_btList.list_of_items[0].size_requested;
00461   if (size%8 != 0) m_btList.list_of_items[0].size_requested+=8-size%8;
00462   if (size > m_dmaBufSize) {
00463     CMEM_SegmentFree(m_dmaBuf);
00464     ret = CMEM_SegmentAllocate(size+0x1000, "VmeInterface DMA", &m_dmaBuf); 
00465     if (ret) {
00466       m_dmaBufSize = 0;
00467       throw VmeException(VmeException::MAP_ERROR, DMAMEM_ALLOC_ERROR); 
00468     } else {
00469       m_dmaBufSize = size+0x1000;
00470     }
00471   }
00472   // Perform DMA transfer
00473   unsigned long pcidma;
00474   unsigned long *bdma;
00475   CMEM_SegmentPhysicalAddress(m_dmaBuf, &pcidma);
00476   CMEM_SegmentVirtualAddress (m_dmaBuf, (unsigned long*)&bdma);
00477   if (pcidma%4 != 0) throw VmeException(VmeException::MAP_ERROR, PCIADD_MISALIGNED); 
00478   if ((pcidma-vmebusAddr)%8 != 0) throw VmeException(VmeException::MAP_ERROR, PCI_VME_MISALIGNED); 
00479   m_btList.list_of_items[0].system_iobus_address = pcidma;
00480   //int btId; 
00481   ret = VME_BlockTransfer(&m_btList, 10000);
00482   //ret = VME_BlockTransferInit(&m_btList, &btId);
00483   //ret = VME_BlockTransferStart(btId);
00484   //ret = VME_BlockTransferDump();
00485   //ret = VME_BlockTransferWait(btId, 10000, &m_btList);
00486   //ret = VME_BlockTransferEnd(btId);
00487   if (ret) {
00488     throw VmeException(VmeException::MAP_ERROR, BT_READ_ERROR+ret); 
00489   }
00490   // Copy the output to the user buffer
00491   int i;
00492   for (i=0; i<(size>>2); i++) {
00493     buf[i] = bdma[i];
00494   }   
00495 }
00496 
00497 void RCCVmeInterface::m_blockTransferWrite(const unsigned long *buf) {
00498   unsigned long ret;
00499 
00500   long vmebusAddr = m_btList.list_of_items[0].vmebus_address;
00501   if (vmebusAddr%4 != 0) throw VmeException(VmeException::MAP_ERROR, VMEADD_MISALIGNED); 
00502 
00503   // Check if the dma buffer needs to be enlarged
00504   long size = m_btList.list_of_items[0].size_requested;
00505   if (size%8 != 0) m_btList.list_of_items[0].size_requested+=8-size%8;
00506   if (size > m_dmaBufSize) {
00507     CMEM_SegmentFree(m_dmaBuf);
00508     ret = CMEM_SegmentAllocate(size+0x1000, "VmeInterface DMA", &m_dmaBuf); 
00509     if (ret) {
00510       m_dmaBufSize = 0;
00511       throw VmeException(VmeException::MAP_ERROR, DMAMEM_ALLOC_ERROR); 
00512     } else {
00513       m_dmaBufSize = size+0x1000;
00514     }
00515   }
00516   // Copy the input to the dma buffer
00517   int i;
00518   unsigned long pcidma;
00519   unsigned long *bdma;
00520   CMEM_SegmentPhysicalAddress(m_dmaBuf, &pcidma);
00521   CMEM_SegmentVirtualAddress(m_dmaBuf,  (unsigned long *)&bdma);
00522   if (pcidma%4 != 0) throw VmeException(VmeException::MAP_ERROR, PCIADD_MISALIGNED); 
00523   if ((pcidma-vmebusAddr)%8 != 0) throw VmeException(VmeException::MAP_ERROR, PCI_VME_MISALIGNED); 
00524   for (i=0; i<(size>>2); i++) {
00525     bdma[i] = buf[i];
00526   }   
00527   // Perform DMA transfer
00528   m_btList.list_of_items[0].system_iobus_address = pcidma; 
00529   //int btId; 
00530   ret = VME_BlockTransfer(&m_btList, 10000);
00531   //ret = VME_BlockTransferInit(&m_btList, &btId);
00532   //ret = VME_BlockTransferStart(btId);
00533   //ret = VME_BlockTransferDump();
00534   //ret = VME_BlockTransferWait(btId, 10000, &m_btList);
00535   //ret = VME_BlockTransferEnd(btId);
00536   if (ret) {
00537     throw VmeException(VmeException::MAP_ERROR, BT_WRITE_ERROR+ret); 
00538   }
00539 }
00540 
00541 unsigned long RCCVmeInterface::registerPort(VmePort &port) {
00542   int handle;
00543   int ret;
00544   unsigned int ip;
00545   VME_MasterMap_t master_map = {0x0, 0x1000, VME_A32, 0};
00546 
00547   master_map.vmebus_address = port.getBaseAddress();
00548   master_map.window_size = port.getMapSize();
00549   master_map.address_modifier =  m_RCCAddrMod(port.getAddrMod());
00550   ret = VME_MasterMap(&master_map, &handle);
00551 
00552   for (ip=0; ip<m_ports.size(); ip++) {
00553     if (m_ports[ip] == NULL) {
00554       m_ports[ip] = &port;
00555       return handle;
00556     }
00557   }
00558   m_ports.push_back(&port);
00559   return handle;
00560 }         
00561 
00562 void RCCVmeInterface::deletePort(VmePort &port) {
00563   unsigned int ip;
00564   int handle = port.getHandle();
00565   VME_MasterUnmap(handle);
00566   for (ip=0; ip<m_ports.size(); ip++) {
00567     if (m_ports[ip] == &port) {
00568       m_ports[ip] = NULL;
00569     }
00570   }
00571 }
00572 
00573 void *RCCVmeInterface::getPortMap(const unsigned long handle) {
00574   u_int value;
00575   VME_MasterMapVirtualAddress(handle, &value);
00576   return (void *)value;
00577 }
00578   
00579 int RCCVmeInterface::m_RCCAddrMod(VmeInterface::AddrMod mod) {
00580   switch (mod) {
00581   case A16:
00582     return VME_A16;
00583     break;
00584   case A24:
00585     return VME_A24;
00586     break;
00587   case A32:
00588   default:
00589     return VME_A32;
00590     break;
00591   };
00592 }
00593 
00594 void RCCVmeInterface::busErrorReport() {
00595 
00596   if (getBusErrors() != 0) throw VmeException(VmeException::BUS_ERROR, VME_BUSERROR); 
00597 }
00598 
00599 void RCCVmeInterface::busErrorReport(const unsigned long handle) {
00600   if (getBusErrors() != 0) {
00601     // Loop over the registered ports
00602     unsigned int ip;
00603     for (ip=0; ip<m_ports.size(); ip++) {
00604       if (handle == m_ports[ip]->getHandle()) {  
00605         if (m_ports[ip]->getExceptionTrapping()) {
00606       throw VmeException(VmeException::BUS_ERROR, VME_BUSERROR, m_ports[ip]);
00607     }
00608       }
00609     }
00610   }
00611 }
00612 
00613 void RCCVmeInterface::busErrorReport(VmePort &port) {
00614   if (getBusErrors() != 0) throw VmeException(VmeException::BUS_ERROR, VME_BUSERROR, &port); 
00615 }
00616 
00617 std::string RCCVmeInterface::getErrorMessage(const long errcod) {
00618   char err[256];
00619   VME_ErrorString(errcod, err);
00620   return err;
00621 }
00622 
00623 long RCCVmeInterface::getBusErrors() {
00624   long be = m_busErrors;
00625   m_busErrors = 0;
00626   VME_BusErrorInfoGet(&m_busErrInfo);
00627   return be;
00628 }

Generated on Thu Dec 22 20:17:07 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5