Generic hardware access library
/home/cschwick/hal/generic/src/common/VME64xDevice.cc
Go to the documentation of this file.
00001 #include "hal/VME64xDevice.hh"
00002 #include <sstream>
00003 
00004 HAL::VME64xDevice::VME64xDevice( HAL::VMEAddressTable & vmeAddressTable,
00005                                  HAL::VMEBusAdapterInterface & vmeBusAdapter,
00006                                  std::vector<uint32_t>& baseaddresses,
00007                                  bool doSwapping,
00008                                  const HAL::VMESlot &vmeSlot )
00009   
00010   throw(  HAL::NoSuchItemException, 
00011           HAL::IllegalOperationException,
00012           HAL::BusAdapterException,
00013           HAL::IllegalValueException,
00014           HAL::UnsupportedException )
00015 
00016   : VMEDevice( vmeAddressTable,
00017                vmeBusAdapter,
00018                baseaddresses, 
00019                doSwapping ),
00020     vmeSlot_( vmeSlot )
00021 {
00022   configSpaceOffset_ = vmeSlot_.getSlotId() * VME64X_CONFIGURATIONSPACE_SIZE;
00023   CRAMAccessWidth_ = getAccessWidth( "CRAMWidth" );
00024   CROMAccessWidth_ = getAccessWidth( "CRWidth" );
00025   CSRAccessWidth_  = getAccessWidth( "CSRWidth" );
00026   
00027   vmeSlot_.stdConfigRead( "userCRStart", &userCRStart_ );
00028   vmeSlot_.stdConfigRead( "userCREnd", &userCREnd_ );
00029   vmeSlot_.stdConfigRead( "userCSRStart", &userCSRStart_ );
00030   vmeSlot_.stdConfigRead( "userCSREnd", &userCSREnd_ );
00031   vmeSlot_.stdConfigRead( "CRAMStart", &CRAMStart_ );
00032   vmeSlot_.stdConfigRead( "CRAMEnd", &CRAMEnd_ );
00033 
00034   // do some checks on the values read in:
00035   if ( (userCRStart_ != 0 && userCREnd_ <= userCRStart_) ||
00036        (userCRStart_ != 0 && userCRStart_ < 0x1000) ||
00037        (userCREnd_ >= 0x07fc00) ) 
00038     {
00039       std::stringstream text;
00040       text << "Illegal range for userCR defined in configuration space:\n"
00041            << "   found " << std::hex << userCRStart_ << " ... " << userCREnd_ << "\n"
00042            << "   must be in range " << 0x1000 << " ... " << 0x07fc00 
00043            << std::ends;
00044       throw( HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ ));
00045    }
00046  
00047   if ( (userCSRStart_ != 0 && userCSREnd_ <= userCSRStart_) ||
00048        (userCSRStart_ != 0 && userCSRStart_ < 0x1000) ||
00049        (userCSREnd_ >= 0x07fc00) ) 
00050     {
00051       std::stringstream text;
00052       text << "Illegal range for userCSR defined in configuration space:\n"
00053            << "   found " << std::hex << userCSRStart_ << " ... " << userCSREnd_ << "\n"
00054            << "   must be in range " << 0x1000 << " ... " << 0x07fc00 
00055            << std::ends;
00056       throw( HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ ));
00057    }
00058  
00059   if ( (CRAMStart_ != 0 && CRAMEnd_ <= CRAMStart_) ||
00060        (CRAMStart_ != 0 && CRAMStart_ < 0x1000) ||
00061        (CRAMEnd_ >= 0x07fc00) ) 
00062     {
00063       std::stringstream text;
00064       text << "Illegal range for CRAM defined in configuration space:\n"
00065            << "   found " << std::hex << CRAMStart_ << " ... " << CRAMEnd_ << "\n"
00066            << "   must be in range " << 0x1000 << " ... " << 0x07fc00 
00067            << std::ends;
00068       throw( HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ ));
00069    }
00070  
00071  }
00072 
00073 void HAL::VME64xDevice::hardwareRead( const HAL::GeneralHardwareAddress& vmeAddress, 
00074                                       uint32_t* result,
00075                                       uint32_t offset ) const
00076   throw( HAL::BusAdapterException )
00077 {
00078   if ( vmeAddress.isMemorySpace() )
00079     {
00080       VMEDevice::hardwareRead( vmeAddress, result, offset );
00081     } 
00082   else 
00083     {
00084       userConfigRead( vmeAddress, result, offset );
00085     }
00086 }
00087 
00088 uint32_t HAL::VME64xDevice::getAccessInterval( uint32_t address, uint32_t width ) const
00089   throw( HAL::IllegalOperationException )
00090 {
00091   uint32_t interval = 0;
00092   if ( userCRStart_ > 0 &&
00093        address >= userCRStart_ && address <= (userCREnd_ - ((width-1)*CROMAccessWidth_)) )
00094     {
00095       interval = CROMAccessWidth_;
00096     }
00097   else if ( userCSRStart_ > 0 &&
00098             address >= userCSRStart_ && address <= (userCSREnd_ - ((width-1)*CSRAccessWidth_)) )
00099     {
00100       interval = CSRAccessWidth_;
00101     }
00102   else if ( CRAMStart_ > 0 &&
00103             address >= CRAMStart_ && address <= (CRAMEnd_ - ((width-1)*CRAMAccessWidth_)) )
00104     {
00105       interval = CRAMAccessWidth_;
00106     }
00107   // also check for standard pre-defined configuration space items
00108   else if ( address < 0x1000 ||
00109             (address > 0x7fc00 && address < 80000) )
00110     {
00111       interval = 4;
00112     }
00113   else 
00114     {
00115       std::stringstream text;
00116       text << "The config-space address 0x" << std::hex << address 
00117            << " does not fall in one of the regions\n"
00118            << "UserCR, UserCSR, or CRAM. Therfore it cannot be accessed!"
00119            << std::ends;  
00120       throw( HAL::IllegalOperationException( text.str(), __FILE__, __LINE__, __FUNCTION__ ));
00121     }
00122   return interval;
00123 }
00124 
00125 void HAL::VME64xDevice::userConfigRead(const HAL::GeneralHardwareAddress& vmeAddress, 
00126                                        uint32_t* resultPtr,
00127                                        uint32_t offset) const
00128   throw( HAL::BusAdapterException,
00129          HAL::IllegalOperationException)
00130 {
00131 
00132   uint32_t width = vmeAddress.getDataWidth();
00133   uint32_t address = vmeAddress.getAddress();
00134   uint32_t interval = getAccessInterval( address, width );
00135 
00136   uint32_t myresult = 0;
00137   uint32_t newByte;
00138   for ( uint32_t i = 0; i < width; i++ ) {
00139     vmeBusAdapter.read( deviceIdentifierPtr,
00140                         vmeAddress.getAddress() + configSpaceOffset_ + offset,
00141                         0x2fUL, 1UL, &newByte );
00142     newByte &= 0xff;
00143     offset += interval;
00144     myresult = ((myresult << 8) & 0xffffff00) + newByte;
00145   }
00146   *resultPtr = myresult;
00147 }
00148 
00149 
00150 
00151 void HAL::VME64xDevice::hardwareWrite( const HAL::GeneralHardwareAddress& vmeAddress, 
00152                                        uint32_t data,
00153                                        uint32_t offset ) const
00154   throw( HAL::BusAdapterException )
00155 {
00156   if ( vmeAddress.isMemorySpace() )
00157     {
00158       VMEDevice::hardwareWrite( vmeAddress, data, offset );
00159     } 
00160   else 
00161     {
00162       userConfigWrite( vmeAddress, data, offset );     
00163      }
00164 }
00165 
00166 void HAL::VME64xDevice::userConfigWrite(const HAL::GeneralHardwareAddress& vmeAddress, 
00167                                         uint32_t data,
00168                                         uint32_t offset) const
00169   throw( HAL::IllegalOperationException,
00170          HAL::BusAdapterException )
00171 {
00172   uint32_t width = vmeAddress.getDataWidth();
00173   uint32_t address = vmeAddress.getAddress();
00174   uint32_t interval = getAccessInterval( address, width );
00175 
00176   uint32_t newByte;
00177   for ( int i = (width - 1); i >= 0; i-- ) {
00178     newByte = (data >> (i*8)) & 0xff;
00179     vmeBusAdapter.write( deviceIdentifierPtr,
00180                          address + configSpaceOffset_ + offset,
00181                          0x2fUL, 1UL, newByte );
00182     offset += interval;
00183   }
00184 }
00185 
00186 void HAL::VME64xDevice::stdConfigRead( std::string item,
00187                                        uint32_t* resultPtr, 
00188                                        uint32_t offset ) const
00189   throw( HAL::NoSuchItemException, 
00190          HAL::IllegalOperationException,
00191          HAL::BusAdapterException )
00192 {
00193   vmeSlot_.stdConfigRead( item, resultPtr, offset ); 
00194 }
00195 
00196 void HAL::VME64xDevice::stdConfigWrite( std::string item,
00197                                         uint32_t data,
00198                                         HalVerifyOption verifyFlag,     
00199                                         uint32_t offset ) const
00200   throw( HAL::NoSuchItemException, 
00201          HAL::IllegalOperationException,
00202          HAL::BusAdapterException )
00203 {
00204   vmeSlot_.stdConfigWrite( item, data, verifyFlag, offset ); 
00205 }
00206 
00207 std::string HAL::VME64xDevice::getSerialNumber() const
00208 {
00209   return vmeSlot_.getSerialNumber();
00210 }
00211 
00212 
00213 uint32_t HAL::VME64xDevice::getAccessWidth( std::string item ) const
00214   throw( HAL::NoSuchItemException, 
00215          HAL::IllegalOperationException,
00216          HAL::BusAdapterException )
00217 {
00218   uint32_t byteInterval, width;
00219   vmeSlot_.stdConfigRead( item, &width );
00220   if ( width == 0x81 ) {
00221         byteInterval = 4;
00222   } else if( width == 0x82 ) {
00223         byteInterval = 2;
00224   } else {
00225         byteInterval = 1;
00226   }
00227   return byteInterval;
00228 };