Generic hardware access library
|
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 };