CVMEptr.h

Go to the documentation of this file.
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 /*
00018   \class CVMEptr
00019   \file CVMEptr.h
00020 
00021   Encapsulates a CVMEptr object. CVMEptrs are the lowest level of the
00022   vme module memory mapping hierarchy. They perform the actual mapping
00023   via the CVMEInterface class. They directly manipulate the registers
00024   and scale the pointer offsets.
00025 
00026   Author:
00027      Jason Venema
00028      NSCL
00029      Michigan State University
00030      East Lansing, MI 48824-1321
00031      mailto: venemaja@msu.edu
00032 */
00033 
00034 #ifndef __CVMEPTR_H
00035 #define __CVMEPTR_H
00036 
00037 #ifndef __SYS_MMAN_H
00038 #include <sys/mman.h>
00039 #endif
00040 
00041 #ifndef __UNISTD_H
00042 #include <unistd.h>
00043 #endif
00044 
00045 #ifndef __TYPES_H
00046 #include <sys/types.h>
00047 #endif
00048 
00049 
00050 #ifndef __HISTOTYPES_H
00051 #include <histotypes.h>
00052 #endif
00053 
00054 #ifndef __RANGEERROR_H
00055 #include <RangeError.h>
00056 #endif
00057 
00058 #ifndef __CVMEINTERFACE_H
00059 #include <CVMEInterface.h>
00060 #endif
00061 
00062 #ifndef __STRING
00063 #include <string>
00064 #endif
00065 
00066 #ifndef __MMAPERROR_H
00067 #include <MmapError.h>
00068 #endif
00069 
00070 template<class T>
00071 class CVMEptr
00072 {
00073   UInt_t             m_nLength;  // the length of the mmap
00074   volatile Address_t m_pStart;   // the starting address of the mmap
00075   void*              m_pHandle;  // Handle to VME interface device.
00076   Int_t              m_nOffset;
00077   UInt_t             m_nSpace;   // The address space of the mapping
00078   UInt_t             m_nBase;    // The base address in the crate
00079 
00080  public:
00081   typedef enum _Space {
00082     a16 = 0,
00083     a24 = 1,
00084     a32 = 3,
00085     geo = 4
00086   } Space;
00087 
00088  public:
00089   // Default constructor and Copy Constructor 
00090   CVMEptr<T>(UInt_t space, UInt_t base, UInt_t length, UInt_t crate=0);
00091   CVMEptr<T>(Space space, UInt_t base, UInt_t length, UInt_t crate=0);
00092   CVMEptr<T>(const CVMEptr& aCVMEptr);
00093   CVMEptr<T>();
00094 
00095   // operator= Assignment operator
00096   CVMEptr<T>& operator= (const CVMEptr& aCVMEptr);
00097 
00098   // Operator== equality operator
00099   int operator== (const CVMEptr<T>& aCVMEptr)
00100     {
00101       return ((m_nOffset == aCVMEptr.m_nOffset) &&
00102               (m_nLength == aCVMEptr.m_nLength) &&
00103               (m_pStart  == aCVMEptr.m_pStart));
00104     }
00105 
00106   // Destructor
00107   ~CVMEptr<T>();
00108 
00109  protected:
00110 
00111   // Protected function member:
00112   // This does the actual mmapping of the VME module
00113   void CreateMap(UInt_t space, UInt_t base, UInt_t length,
00114                  UInt_t crate = 0);
00115 
00116   // Public accessor functions to data members
00117  public:
00118 
00119   UInt_t getOffset() const {
00120     return m_nOffset;
00121   }
00122   UInt_t getLength() const {
00123     return m_nLength;
00124   }
00125   Address_t getStart() const {
00126     return m_pStart;
00127   }
00128   void* getHandle() const {
00129     return m_pHandle;
00130   }
00131   UInt_t getSpace() const {
00132     return m_nSpace;
00133   }
00134   UInt_t getBase() const {
00135     return m_nBase;
00136   }
00137   Address_t getgenptr(UInt_t nOffset);
00138   Address_t getcurrptr();
00139 
00140   // Protected mutator functions to data members
00141  public:
00142   void setOffset(UInt_t am_nOffset) {
00143     m_nOffset = am_nOffset;
00144   }
00145   void setLength(UInt_t am_nLength) {
00146     m_nLength = am_nLength;
00147   }
00148   void setStart(Address_t pStart) {
00149     m_pStart = pStart;
00150   }
00151   void setHandle(void* am_pHandle) {
00152     m_pHandle = am_pHandle;
00153   }
00154   void setSpace(UInt_t am_nSpace) {
00155     m_nSpace = am_nSpace;
00156   }
00157   void setBase(UInt_t am_nBase) {
00158     m_nBase = am_nBase;
00159   }
00160 
00161   // Public member functions
00162  public:
00163   // Pointer dereference
00164   T& operator*();
00165   T* operator->();
00166 
00167   // Indexing
00168   T& operator[] (UInt_t nOffset);
00169   
00170   // Pointer addition/subtraction
00171   CVMEptr<T> operator+(UInt_t nOffset);
00172   CVMEptr<T> operator-(UInt_t nOffset);
00173   CVMEptr<T>& operator+=(UInt_t nOffset);
00174   CVMEptr<T>& operator-=(UInt_t nOffset);
00175 
00176   // Pointer pre-increment/decrement
00177   CVMEptr<T>& operator++();
00178   CVMEptr<T>& operator--();
00179 
00180   // Pointer post-increment/decrement
00181   CVMEptr<T> operator++(Int_t);
00182   CVMEptr<T> operator--(Int_t);
00183 };
00184 
00185 #endif
00186 
00187 /*
00188   \fn CVMEptr(VmeSpace space, UInt_t base, UInt_t length)
00189 
00190   Operation Type:
00191      Construction
00192 
00193   \param  VmeSpace space - enumeration indicating which vme address space 
00194                            to use
00195           UInt_t base - the base (offset) into the mapping
00196           UInt_t length - the length of the mapping
00197 */
00198 
00199 template<class T>
00200 CVMEptr<T>::CVMEptr(UInt_t space, UInt_t base, UInt_t length,
00201                        UInt_t crate) :
00202   m_nOffset(0),
00203   m_nLength(length),
00204   m_nSpace(space),
00205   m_nBase(base)
00206 {
00207   CreateMap(space, base, length, crate);
00208 }
00209 /*
00210   Same as above, but use Space instead of int:
00211 */
00212 template<class T>
00213 CVMEptr<T>::CVMEptr(Space space, UInt_t base, UInt_t length,
00214                        UInt_t crate) :
00215   m_nOffset(0),
00216   m_nLength(length),
00217   m_nSpace(space),
00218   m_nBase(base)
00219 {
00220   CreateMap((int)space, base, length, crate);
00221 }
00222 
00223 
00224 /*
00225   \fn CVMEptr<T>::CVMEptr<T>()
00226 
00227   Operation Type:
00228      Constructor
00229 
00230   Purpose:
00231      Construct an object of this type. Note that no mapping is
00232      performed, and m_nOffset and m_nLength are both set to 0.
00233 */
00234 template<class T>
00235 CVMEptr<T>::CVMEptr()
00236 {
00237   m_nOffset = 0;
00238   m_nLength = 0;
00239 }
00240 
00241 /*
00242   \fn CVMEptr(const CVMEptr& aCVMEptr)
00243 
00244   Operation Type:
00245      Copy construction
00246 
00247   \param CVMEptr aCVMEptr - the CVMEptr to copy
00248 */
00249 template<class T>
00250 CVMEptr<T>::CVMEptr(const CVMEptr& aCVMEptr)
00251 {
00252   m_nOffset = aCVMEptr.m_nOffset;
00253   m_nLength = aCVMEptr.m_nLength;
00254   m_pStart  = aCVMEptr.m_pStart;
00255 }
00256 
00257 /*
00258   \fn CVMEptr& operator= (const CVMEptr& aCVMEptr)
00259 
00260   Operation type:
00261      operator= Assignment operator
00262 
00263   \param CVMEptr& aCVMEptr - reference to the CVMEptr to assign this to
00264 */
00265 template<class T>
00266 CVMEptr<T>&
00267 CVMEptr<T>::operator= (const CVMEptr& aCVMEptr)
00268 {
00269   if(this == &aCVMEptr) return *this;
00270 
00271   m_nOffset = aCVMEptr.m_nOffset;
00272   m_nLength = aCVMEptr.m_nLength;
00273   m_pStart  = aCVMEptr.m_pStart;
00274 
00275   return *this;
00276 }
00277 
00278 /*
00279   \fn CVMEptr<T>::~CVMEptr<T>()
00280   
00281   Operation type:
00282      Destructor
00283 
00284   Purpose: Destructor is responsible for munmapping the module
00285 */
00286 template<class T>
00287 CVMEptr<T>::~CVMEptr<T>()
00288 {
00289 
00290   CVMEInterface::Unmap(m_pHandle, m_pStart, m_nLength);
00291   CVMEInterface::Close(m_pHandle);
00292 }
00293 
00294 /*
00295   \fn void CVMEptr<T>::CreateMap(UInt_t space, UInt_t base, UInt_t length)
00296 
00297   Operation Type:
00298      Map
00299 
00300   \param UInt_t space  - indicates which vme device to open 
00301                          (a16d16, a24d32 or a32d32)
00302          UInt_t base   - the base address of the module which we're mapping to
00303          UInt_t lenght - the length (bytes) of the map
00304          UInt_t crate  - Selects the vme crate.
00305 */
00306 template<class T>
00307 void
00308 CVMEptr<T>::CreateMap(UInt_t space, UInt_t base, UInt_t length, UInt_t crate)
00309 {
00310 
00311   m_nOffset = 0;
00312 
00313   // First open the specified vme device
00314 
00315   try {
00316     switch(space) {
00317     case 0:
00318       m_pHandle = CVMEInterface::Open(CVMEInterface::A16, crate);
00319       break;
00320     case 1:                     // No difference between d16, d32.
00321     case 2:
00322       m_pHandle = CVMEInterface::Open(CVMEInterface::A24, crate);
00323       break;
00324     case 3:
00325       m_pHandle = CVMEInterface::Open(CVMEInterface::A32, crate);
00326       break;
00327     case 4:
00328       m_pHandle = CVMEInterface::Open(CVMEInterface::GEO , crate);
00329       break;
00330     default:
00331       std::cerr << "Default condition in CVMEptr<T> CreateMap switch " << space 
00332            << std::endl;
00333       std::cerr.flush();
00334       
00335       break;
00336     }
00337   }
00338   catch(STD(string)& err) {
00339     STD(string) merr = "CVMEptr<T>::CreateMap - Opening connection to vme device";
00340     merr += '\n';
00341     merr += err;
00342     merr += "\n";
00343     CMmapError me(err.c_str());
00344     throw me; 
00345   }
00346 
00347 
00348   // Determine the page size and page offset
00349 
00350   m_nLength = length;
00351   try {
00352     m_pStart  = CVMEInterface::Map(m_pHandle, base, length);
00353   }
00354   catch (STD(string)& err) {
00355     STD(string) merr("CVMEptr<T>::CreateMap - Unable to perform CVMEInterface::Map");
00356     merr += '\n';
00357     merr += err;
00358     merr += "\n";
00359     throw CMmapError(merr.c_str());
00360 
00361   }
00362 
00363   
00364 }
00365 
00366 
00367 /*
00368   \fn T& CVMEptr<T>::operator*()
00369 
00370   Operation Type:
00371      Pointer dereference
00372 
00373   Purpose:
00374      Return the value stored at location m_nOffset in the mapped 
00375      address space. Throws an exception if the value is out of range.
00376 */
00377 template<class T>
00378 T&
00379 CVMEptr<T>::operator*()
00380 {
00381   if( (m_nOffset < 0) || (m_nOffset >= m_nLength)) {
00382     throw CRangeError (0, m_nLength, m_nOffset, 
00383                        "CVMEptr<T>::operator*() - outside of address window");
00384 
00385   }
00386 
00387   Address_t pVa = (Address_t)(m_nOffset*sizeof(T) + (UInt_t)m_pStart);
00388   return (*(T*)pVa);
00389 }
00390 
00391 /*
00392   \fn T* CVMEptr<T>::operator->()
00393 
00394   Operation Type:
00395      Pointer dereference
00396 
00397   Purpose:
00398      Return a pointer to the value at location m_nOffset
00399      into the mapped address space. Throws an exception if the value is
00400      out of range.
00401 */
00402 template<class T>
00403 T*
00404 CVMEptr<T>::operator->()
00405 {
00406   if((m_nOffset < 0) || (m_nOffset >= m_nLength)) {
00407     throw CRangeError(0, m_nLength, m_nOffset, 
00408                  "CVMEptr<T>::operator->() - outside of address window");
00409   }
00410   Address_t pVa = (Address_t)(m_nOffset*sizeof(T) + (UInt_t)m_pStart);
00411   
00412   return (T*)pVa;
00413 }
00414 
00415 /*
00416   \fn T& CVMEptr<T>::operator[] (UInt_t nOffset)
00417 
00418   Operation Type:
00419      Index read/write
00420 
00421   Purpose:
00422      Return the value stored at locaton nOffset into the mapped address
00423      space. Throws an exception if the value is out of range.
00424 
00425   \param UInt_t nOffset - the offset into the address space from which to read.
00426 */
00427 template <class T>
00428 T&
00429 CVMEptr<T>::operator[] (UInt_t nOffset)
00430 {
00431   if((m_nOffset < 0) || (m_nOffset >= m_nLength)) {
00432     throw CRangeError(0, m_nLength, m_nOffset, 
00433                       "CVMEptr<T>::operator[]() - outside of address window");
00434   }
00435   Address_t pVa = (Address_t)(nOffset*sizeof(T) + (UInt_t)m_pStart);
00436 
00437   return (*(T*)pVa);
00438 }
00439 
00440 /*
00441   \fn CVMEptr<T>& CVMEptr<T>::operator+(UInt_t nOffset)
00442 
00443   Operation Type:
00444      Mutator
00445 
00446   Purpose:
00447      Add an offset to the current offset. Throws an exception if this
00448      puts us out of range of the memory map.
00449 
00450   \param UInt_t nOffset - the integer to add to the current offset
00451 */
00452 template<class T>
00453 CVMEptr<T>
00454 CVMEptr<T>::operator+(UInt_t nOffset)
00455 {
00456   if(nOffset+m_nOffset <= m_nLength) {  // make sure we're in bounds
00457     CVMEptr<T> temp = *this;
00458     temp += nOffset;
00459     return temp;
00460   }
00461   else {
00462     CRangeError re(0, m_nOffset, nOffset, 
00463                  "CVMEptr<T>::operator+() - outside of mapped address window");
00464     throw re;
00465   }
00466 }
00467 
00468 /*
00469   \fn CVMEptr<T>& CVMEptr<T>::operator-(UInt_t nOffset)
00470 
00471   Operation Type:
00472      Mutator
00473 
00474   Purpose:
00475      Subtracts an offset to the current offset. Throws an exception if this
00476      puts us out of range of the memory map.
00477 
00478   \param UInt_t nOffset - the integer to subtract from the current offset
00479 */
00480 template<class T>
00481 CVMEptr<T>
00482 CVMEptr<T>::operator-(UInt_t nOffset)
00483 {
00484   if(nOffset <= m_nOffset) {    // make sure we're in bounds
00485     CVMEptr<T> temp = *this;
00486     temp -= nOffset;
00487     return temp;
00488   }
00489   else {
00490     CRangeError re(0, m_nOffset, nOffset,
00491               "CVMEptr<T>::operator-() - outside of mapped addressed window");
00492     throw re;
00493   }
00494 }
00495 
00496 /*
00497   \fn CVMEptr<T>& CVMEptr<T>::operator+=(UInt_t nOffset)
00498 
00499   Operation Type:
00500      Mutator
00501 
00502   Purpose:
00503      Add an offset to the current offset. Throws an exception if this
00504      puts us out of range of the memory map.
00505 
00506   \param UInt_t nOffset - the integer to add to the current offset
00507 */
00508 template<class T>
00509 CVMEptr<T>&
00510 CVMEptr<T>::operator+=(UInt_t nOffset)
00511 {
00512   if(m_nOffset+nOffset <= m_nLength) {
00513     m_nOffset += nOffset;
00514     return *this;
00515   }
00516   else {
00517     CRangeError re(0, m_nOffset, nOffset,
00518                "CVMEptr<T>::operator+=() - outside of mapped address window");
00519     throw re;
00520   }
00521 }
00522 
00523 /*
00524   \fn CVMEptr<T>& CVMEptr<T>::operator-=(UInt_t nOffset)
00525 
00526   Operation Type:
00527      Mutator
00528 
00529   Purpose:
00530      Subtract an offset to the current offset. Throws an exception if this
00531      puts us out of range of the memory map.
00532 
00533   \param UInt_t nOffset - the integer to subtract from the current offset
00534 */
00535 template<class T>
00536 CVMEptr<T>&
00537 CVMEptr<T>::operator-=(UInt_t nOffset)
00538 {
00539   if(m_nOffset-nOffset > 0) {
00540     m_nOffset -= nOffset;
00541     return *this;
00542   }
00543   else {
00544     CRangeError re(0, m_nOffset, nOffset,
00545                "CVMEptr<T>::operator-=() - outside of mapped address window");
00546   }
00547 }
00548 
00549 /*
00550   \fn CVMEptr<T>& CVMEptr<T>::operator++()
00551   
00552   Operation Type:
00553      Mutator
00554 
00555   Purpose:
00556      (Pre)Increment the current offset. Throws an exception if this puts
00557      m_nOffset past the length of the memory map.
00558 */
00559 template<class T>
00560 CVMEptr<T>&
00561 CVMEptr<T>::operator++()
00562 {
00563   if(m_nOffset < m_nLength) {
00564     m_nOffset++;
00565     return *this;
00566   }
00567   else {
00568     STD(string) reason = "CVMEptr<T>::operator++() - reference to address which\n";
00569     reason += "is greater than map size";
00570     CRangeError re(0, m_nOffset, m_nOffset+1, reason);
00571     throw re;
00572   }
00573 }
00574 
00575 /*
00576   \fn CVMEptr<T>& CVMEptr<T>::operator--()
00577   
00578   Operation Type:
00579      Mutator
00580 
00581   Purpose:
00582      (Pre)Decrement the current offset. Throws an exception if this puts
00583      m_nOffset less than 0.
00584 */
00585 template<class T>
00586 CVMEptr<T>&
00587 CVMEptr<T>::operator--()
00588 {
00589   if(m_nOffset > 0) {
00590     m_nOffset--;
00591     return *this;
00592   }
00593   else {
00594     STD(string) reason = "CVMEptr<T>::operator--() - reference to address which\n";
00595     reason += "is less than map size";
00596     CRangeError re(0, m_nOffset, m_nOffset-1, reason);
00597     throw re;
00598   }
00599 }
00600 
00601 /*
00602   \fn CVMEptr<T>& CVMEptr<T>::operator++(Int_t)
00603 
00604   Operation type:
00605      Mutator
00606 
00607   Purpose:
00608      (Post)Increment the current offset. Throws an exception if this puts
00609      us past the length of the map.
00610 
00611   \param Int_t - dummy parameter indicates this is a 
00612                  post-increment operator
00613 */
00614 template<class T>
00615 CVMEptr<T>
00616 CVMEptr<T>::operator++(Int_t)
00617 {
00618   if(m_nOffset < m_nLength) {
00619     CVMEptr<T> p(*this);
00620     operator++();
00621     return p;
00622   }
00623   else {
00624     STD(string) reason = "CVMEptr<T>::operator++() - reference to memory address\n";
00625     reason += "which is greater than the size of the map";
00626     CRangeError re(0, m_nOffset, m_nOffset+1, reason);
00627     throw re;
00628   }
00629 }
00630 
00631 /*
00632   \fn CVMEptr<T>& CVMEptr<T>::operator--(Int_t)
00633 
00634   Operation type:
00635      Mutator
00636 
00637   Purpose:
00638      (Post)Decrement the current offset. Throws an exception if this puts
00639      us before the beginning of the memory map.
00640 
00641   \param Int_t - dummy parameter indicates this is a 
00642                  post-decrement operator
00643 */
00644 template<class T>
00645 CVMEptr<T>
00646 CVMEptr<T>::operator--(Int_t)
00647 {
00648   if(m_nOffset > 0) {
00649     CVMEptr<T> p(*this);
00650     operator--();
00651     return p;
00652   }
00653   else {
00654     STD(string) reason = "CVMEptr<T>::operator--() reference to memory address\n";
00655     reason += "which is less than the start address of the map";
00656     CRangeError re(0, m_nOffset, m_nOffset-1, reason);
00657     throw re;
00658   }
00659 }
00660 
00661 /*
00662   \fn Address_t CVMEptr<T>::getgenptr(UInt_t nOffset)
00663 
00664   Operation type:
00665      Selector
00666 
00667   Purpose:
00668      Return a pointer to the current address+offset into the module
00669 
00670   \param UInt_t nOffset - an offset to use to determine the pointer
00671 */
00672 template<class T>
00673 Address_t
00674 CVMEptr<T>::getgenptr(UInt_t nOffset)
00675 {
00676   Address_t p = (Address_t)(nOffset*sizeof(T) + (UInt_t)m_pStart);
00677   if(p) return p;
00678   else return (Address_t)kpNULL;
00679 }
00680 
00681 /*
00682   \fn Address_t CVMEptr<T>::getcurrptr(UInt_t nOffset)
00683 
00684   Operation Type:
00685      Selector
00686 
00687   Purpose:
00688      Return a pointer to the current address+current offset into the module
00689 */
00690 template<class T>
00691 Address_t
00692 CVMEptr<T>::getcurrptr()
00693 {
00694   Address_t p = (Address_t)(m_nOffset*sizeof(T) + (UInt_t)m_pStart);
00695   if(p) return p;
00696   else return (Address_t)kpNULL;
00697 }

Generated on Wed Sep 17 08:38:09 2008 for NSCL Device support. by  doxygen 1.5.1