00001 /* 00002 This software is Copyright by the Board of Trustees of Michigan 00003 State University (c) Copyright 2005. 00004 00005 You may use this software under the terms of the GNU public license 00006 (GPL). The terms of this license are described at: 00007 00008 http://www.gnu.org/licenses/gpl.txt 00009 00010 Author: 00011 Ron Fox 00012 NSCL 00013 Michigan State University 00014 East Lansing, MI 48824-1321 00015 */ 00016 00017 static const char* Copyright= "(C) Copyright Michigan State University 2002, All rights reserved";/* 00018 ** camacmap.c: 00019 ** Contains daq interfaces to the Bit3/CBD8210 branch highway device. 00020 ** Access to the CAMAC crate is via pointer dereferences into a virtual 00021 ** address space which maps to the CAMAC space as follows: 00022 ** base + |bbb|ccc|nnnnn|aaaa|fffff|w|0 00023 ** (each letter in the set above is a bit) where: 00024 ** bbb - Is the branch to reference 00025 ** ccc - Is a crate within the branch (note that the VME controller 00026 ** registers live in crate 0. 00027 ** nnnnn - Is the CAMAC slot. 00028 ** aaaa - Is the subaddress within the slot. 00029 ** fffff - Is the function code to execute in the selected module. 00030 ** w - Is 1 for word accesses, and 0 is for longword (24 bit) access. 00031 ** 00032 ** Author: 00033 ** Ron Fox 00034 ** NSCL 00035 ** Michigan State University 00036 ** East Lansing, MI 48824-1321 00037 ** (c) Copyright NSCL 1999 All rights reserved. 00038 ** 00039 ** Acknowledgements: 00040 ** Natalie Kruszinska at Nikhef who wrote the Bit 3 device driver, 00041 ** Eric Kasten at NSCL who made it work and gave me code samples on which 00042 ** to base this file. 00043 */ 00044 /* 00045 $Header$ 00046 00047 Change log: 00048 00049 $Log$ 00050 Revision 8.3 2006/01/05 17:30:31 ron-fox 00051 Work around some issues with rethrowing exceptions across constructors 00052 in shared objects...bouncing back and forth. Exceptions caught by 00053 ReadoutStateMachine are now reported at that level before being rethrown. 00054 00055 Revision 8.2 2005/06/24 11:30:38 ron-fox 00056 Bring the entire world onto the 8.2 line 00057 00058 Revision 4.2 2004/11/16 15:24:48 ron-fox 00059 - Port to the gnu 3.x compiler set. 00060 - Integrate buid of tests. 00061 - Integrate build of docos. 00062 00063 Revision 1.2 2004/11/16 15:23:29 ron-fox 00064 - Port -> gcc/g++ 3.x 00065 - Support integrated test building. 00066 - Support integrated doxygen docu7mentation building. 00067 00068 Revision 1.1 2003/12/03 19:29:05 ron-fox 00069 Add generic CAMAC support to the library. 00070 00071 Revision 3.1 2003/03/22 04:03:46 ron-fox 00072 Added SBS/Bit3 device driver. 00073 00074 Revision 2.1 2003/02/11 16:44:58 ron-fox 00075 Retag to version 2.1 to remove the weird branch I accidently made. 00076 00077 Revision 1.2 2003/02/05 18:06:17 ron-fox 00078 Catch up on drift between Readout and the snapshot from which we started 00079 the port to autotools. 00080 00081 Revision 2.7 2002/12/30 18:46:57 fox 00082 Support the WIENER VC/CC32 crate controller hardware thanks to 00083 Dave Caussyn at FSU (caussyn@nucmar.physics.fsu.edu) 00084 00085 Revision 2.6 2002/11/20 16:03:09 fox 00086 Support multiple VME crates and CAMAC Branches spread across the multiple VME 00087 crates. 00088 00089 Revision 2.5 2002/10/22 12:37:23 fox 00090 Straighten out dates in copyright notices in files. 00091 00092 // Revision 2.4 2002/10/10 12:54:25 fox 00093 // Remove multiple copyright strings. 00094 // 00095 // Revision 2.3 2002/10/09 11:27:46 fox 00096 // Add copyright/license stamp. 00097 // 00098 // Revision 2.2 2002/07/02 15:12:23 fox 00099 // Go to 2.xx based releases (recover from client crash too). 00100 // 00101 // Revision 2.1 2002/07/02 15:05:34 fox 00102 // Transition to 2.1 releases 00103 // 00104 // Revision 1.1 2002/07/01 17:37:01 fox 00105 // - Made camacmap.c ->camacmap.cpp 00106 // - The world use CVMEInterface:: rather than direct device access to abstract 00107 // VME crate access. 00108 // 00109 */ 00110 #include <config.h> 00111 00112 #include <stdlib.h> 00113 #include <stdio.h> 00114 #include <string.h> 00115 #include <signal.h> 00116 #include <setjmp.h> 00117 #include <unistd.h> 00118 #include <errno.h> 00119 #include <sys/types.h> 00120 #include <sys/stat.h> 00121 #include <sys/wait.h> 00122 #include <sys/mman.h> 00123 #include <time.h> 00124 #include <sys/time.h> 00125 #include <fcntl.h> 00126 #include <ctype.h> 00127 #include <sys/ioctl.h> 00128 #include <math.h> 00129 #include <assert.h> 00130 #include <CVMEInterface.h> 00131 #include <camac.h> 00132 #include <Iostream.h> 00133 00134 #include <CVMEInterface.h> 00135 00136 #ifdef HAVE_STD_NAMESPACE 00137 using namespace std; 00138 #endif 00139 00140 #define VMECRATES 16 00141 #define BRANCHESINCRATE 8 00142 00143 00144 #define DEF_SIGNAL SIGUSR1 00145 #define DEF_VECTOR -1 00146 #define DEF_IRQ 2 00147 00148 00149 /* This stuff is all pretty obsolete I'm guessing. - RF */ 00150 00151 #define PAGE_SIZE 4096 00152 #define SLOT_SIZE 2048 00153 #define SLOTS_PER_CRATE 25 00154 #define PAGES_PER_CRATE ((SLOTS_PER_CRATE*SLOT_SIZE)/PAGE_SIZE) 00155 #define BRANCHES 8 00156 #define CRATES_PER_BRANCH 8 00157 00158 00159 static char *pCopyright = "(c) NSCL 1999, All rights reserved\n"; 00160 00161 00162 /*===================================================================*/ 00163 void* 00164 daq_OpenCamacDriver() 00165 { 00166 /* Opens the CAMAC device. The user can use the fd returned by 00167 ** this call to to call the other functions in this module: 00168 ** 00169 ** Returns: 00170 ** -1 - IF failure, error in errno. 00171 ** otherwise - the file id open on the device. 00172 */ 00173 00174 return CVMEInterface::Open(CVMEInterface::A24); 00175 } 00176 00177 00178 /*===================================================================*/ 00179 void* 00180 daq_MapCamacSpace(void* fid) 00181 { 00182 /* Maps the entire CAMAC branch highway space and returns a pointer 00183 ** to it to the caller. The branch highway space is assumed to consist 00184 ** of 8 branches with 8 crates all located contiguously in VME space. 00185 ** NOTE: It will be the responsibility of the user of this spaced to 00186 ** ensure that the branches and crates referenced actually exist. 00187 ** 00188 ** Formal Parameters: 00189 ** int fid [in]: 00190 ** File id open on the VME A24/D16 device, returned from a call to 00191 ** daq_OpenCamacDriver(). 00192 ** Returns: 00193 ** Pointer to the CAMAC highway space Virtual address or NULL if 00194 ** the map failed. 00195 */ 00196 void *mbuf; 00197 unsigned long base; 00198 00199 base = (1<<23); /* This is the entire branch base. */ 00200 00201 base = (base&(~(PAGE_SIZE-1))); /* Probably not needed for full br map */ 00202 00203 mbuf = CVMEInterface::Map(fid, base, 00204 (unsigned long)(BRANCHES*CRATES_PER_BRANCH* 00205 PAGE_SIZE*PAGES_PER_CRATE)); 00206 return(mbuf); 00207 } 00208 00209 /*===================================================================*/ 00210 void 00211 daq_UnmapCamacSpace(void* fd, void* pSpace) 00212 { 00213 /* Unmaps the CAMAC address space mapped with daq_MapCamacSpace 00214 ** the mapping is assumed to be the entire size of the CAMAC space 00215 ** which is BRANCHES*CRATES_PER_BRANCH contiguous crates. 00216 ** 00217 ** Formal Parameters: 00218 ** 00219 ** int fd [in]: 00220 ** File descriptor open on the vme driver. 00221 ** void* pSpace [in]: 00222 ** Pointer returned from daq_MapCamacSpace. 00223 */ 00224 00225 CVMEInterface::Unmap(fd, pSpace, 00226 (unsigned long)(BRANCHES*CRATES_PER_BRANCH* 00227 PAGE_SIZE*PAGES_PER_CRATE)); 00228 00229 00230 } 00231 /*===================================================================*/ 00232 void 00233 daq_CloseCamacDriver(void* fid) 00234 { 00235 /* Closes the file id open on the CAMAC device. 00236 ** 00237 ** int fid [in]: 00238 ** File id returned from the call to daq_OpenCamacDriver. 00239 */ 00240 00241 CVMEInterface::Close(fid); 00242 } 00243 00259 static void* vmeFds[VMECRATES]; 00260 void* pBranchBases[VMECRATES*BRANCHESINCRATE]; // static init to NULL 00261 void CESBranchAccess(int nBranch) 00262 { 00263 int nVme = nBranch >> 3; // Extract the VME crate and the 00264 int nB = nBranch & 0x7; // branch inside the crate. 00265 00266 // Note that failures in the map are probably unrecoverable. So we 00267 // allow the exceptions signalled to propagate back up the call stack 00268 // where hopefully smoeone has installed a last chance handler prior to exit. 00269 00270 assert((void*)NULL == (void*)0); // Assumption about init values of ptr array. 00271 assert(nBranch < VMECRATES*BRANCHESINCRATE); // in range branch. 00272 00273 // If the pointer does not exist, then it needs to be mapped: 00274 00275 if(pBranchBases[nBranch] == (void*)NULL) { 00276 if (vmeFds[nVme] == (void*) NULL) { // Need to open the device: 00277 vmeFds[nVme] = CVMEInterface::Open(CVMEInterface::Standard, nVme); 00278 } 00279 // Map the memory: 00280 00281 try { 00282 00283 long nBase = 0x800000 + (nB <<CAMB); 00284 pBranchBases[nBranch] = CVMEInterface::Map(vmeFds[nVme], nBase, 00285 (1L << CAMB)); 00286 } 00287 catch (...) { 00288 cerr << "CVMEInterface::Map threw... rethrowing\n"; 00289 throw; 00290 } 00291 } 00292 } 00302 void WIENERBranchAccess(int nBranch) 00303 { 00304 int nVme = nBranch >> 3; // 8 crates == crates / vme crate. 00305 int nController = nBranch & 0x7; // This is the crate #. 00306 00307 assert ((void*) NULL == (void*)0); // Assume the pointers init to null. 00308 assert(nBranch < VMECRATES*BRANCHESINCRATE); 00309 00310 // Map the crate if the pointer is still NULL: 00311 00312 if(pBranchBases[nBranch] == (void*)NULL) { 00313 if(vmeFds[nVme] == (void*)NULL) { // Need to open the device... 00314 vmeFds[nVme] = CVMEInterface::Open(CVMEInterface::Standard, nVme); 00315 } 00316 00317 // Map the memory for a crate... 00318 // The crates are at : 0x800000 + ((nB * 0x20) << CAMN) 00319 00320 long nBase = 0x800000 + ((nController * 0x20) << CAMN); 00321 pBranchBases[nBranch] = CVMEInterface::Map(vmeFds[nVme], nBase, 00322 0x20 << CAMN); 00323 } 00324 } 00325 00326