Generic hardware access library
|
00001 #include "hal/VMEConfigurationSpaceHandler.hh" 00002 #include <sstream> 00003 #include <iostream> 00004 #include <iomanip> 00005 00006 HAL::VMEConfigurationSpaceHandler::VMEConfigurationSpaceHandler( HAL::VMEBusAdapterInterface& busAdapter ) 00007 : busAdapter_(busAdapter) { 00008 00009 HAL::VMEConfigurationSpaceAddressReader configurationReader; 00010 configurationAddressTablePtr_ = new HAL::VMEAddressTable("VME64x Configuration Space", 00011 configurationReader); 00012 vmeDevicePtr_ = new HAL::VMEConfigurationSpaceDevice( *configurationAddressTablePtr_, 00013 busAdapter ); 00014 } 00015 00016 HAL::VMEConfigurationSpaceHandler::~VMEConfigurationSpaceHandler() { 00017 delete vmeDevicePtr_; 00018 delete configurationAddressTablePtr_; 00019 } 00020 00021 uint32_t HAL::VMEConfigurationSpaceHandler::calculateOffset( uint32_t slot ) const { 00022 return ( slot * VME64X_CONFIGURATIONSPACE_SIZE ); 00023 } 00024 00025 void HAL::VMEConfigurationSpaceHandler::configWrite( std::string item, 00026 uint32_t slot, 00027 uint32_t data, 00028 HalVerifyOption verifyFlag, 00029 uint32_t offset ) const 00030 throw( HAL::NoSuchItemException, 00031 HAL::IllegalOperationException, 00032 HAL::BusAdapterException ) { 00033 offset += calculateOffset( slot ); 00034 vmeDevicePtr_->write( item, data, verifyFlag, offset ); 00035 } 00036 00037 void HAL::VMEConfigurationSpaceHandler::saveWrite( std::string item, 00038 uint32_t slot, 00039 uint32_t data, 00040 HalVerifyOption verifyFlag, 00041 uint32_t offset ) const { 00042 try { 00043 configWrite( item, slot, data, verifyFlag, offset ); 00044 } catch ( HAL::BusAdapterException& e ) { 00045 std::cout << "Internal error while accessing the configuration space via the busAdapter\n (HAL::VMEConfigurationSpaceHandler::saveWrite)" << std::endl; 00046 std::cout << e.what() << std::endl; 00047 exit (-1); 00048 } catch( HAL::HardwareAccessException& e ) { 00049 std::cout << "Internal program error in HAL::VMEConfigurationSpaceHandler::saveWrite: " 00050 << "\ncaught exception:\n" 00051 << e.what() << std::endl; 00052 exit(-1); 00053 } 00054 } 00055 00056 void HAL::VMEConfigurationSpaceHandler::configRead( std::string item, 00057 uint32_t slot, 00058 uint32_t* resultPtr, 00059 uint32_t offset ) const 00060 throw( HAL::NoSuchItemException, 00061 HAL::IllegalOperationException, 00062 HAL::BusAdapterException ) { 00063 offset += calculateOffset( slot ); 00064 vmeDevicePtr_->read( item, resultPtr, offset ); 00065 } 00066 00067 void HAL::VMEConfigurationSpaceHandler::saveRead(std::string item, 00068 uint32_t slot, 00069 uint32_t* resultPtr, 00070 uint32_t offset ) const { 00071 try { 00072 configRead( item, slot, resultPtr, offset ); 00073 } catch ( HAL::BusAdapterException& e ) { 00074 std::cout << "Internal Error while accessing the configuration space via the busAdapter\n (HAL::VMEConfigurationSpaceHandler::saveRead)" << std::endl; 00075 std::cout << e.what() << std::endl; 00076 exit ( -1 ); 00077 } catch( HAL::HardwareAccessException& e ) { 00078 std::cout << "Internal program error in HAL::VMEConfigurationSpaceHandler::saveRead: " 00079 << "\ncaught exception:\n" 00080 << e.what() << std::endl; 00081 exit(-1); 00082 } 00083 } 00084 00085 bool 00086 HAL::VMEConfigurationSpaceHandler::containsVME64xModule( uint32_t slot ) const 00087 throw (HAL::IllegalValueException) { 00088 uint32_t CRIdentifier, CRspecificationId; 00089 bool result; 00090 try{ 00091 configRead( "CR", slot, &CRIdentifier ); 00092 configRead( "specificationId", slot, &CRspecificationId ); 00093 } catch ( HAL::BusAdapterException& e ) { 00094 CRIdentifier = 0; 00095 } catch( HAL::HardwareAccessException& e ) { 00096 std::cout << "Internal program error in HAL::VMEConfigurationSpaceHandler::containsVME64xModule " 00097 << "\ncaught exception:\n" 00098 << e.what() << std::endl; 00099 exit(-1); 00100 } 00101 if ( (CRIdentifier == 0x4352) & (CRspecificationId==0x02) ) { 00102 result = true; 00103 } else { 00104 result = false; 00105 } 00106 return result; 00107 } 00108 00109 bool 00110 HAL::VMEConfigurationSpaceHandler::functionIsImplemented( uint32_t slotId, 00111 uint32_t functionId ) const { 00112 00113 std::ostringstream item; 00114 uint32_t ADEM; 00115 00116 // retrieve raw function data from config space: The ADER is also read 00117 // in case one day we want to support fixed address functions (FAFs). 00118 // item << "ADEM-F" << setw(1)<< setfill('0') << functionId << ends; 00119 // item << "ADEM-F" << dec << setw(1) << functionId << ends; 00120 item << "ADEM-F" << std::setw(1) << functionId; 00121 try { 00122 configRead(item.str(), slotId, &ADEM); 00123 } catch ( HAL::BusAdapterException& e ) { 00124 return false; 00125 } catch ( HAL::HardwareAccessException& e ) { 00126 std::cout << "Internal program error (HAL::VMEConfigurationSpaceHandler::functionIsImplemented)" << std::endl; 00127 std::cout << e.what() << std::endl; 00128 exit(-1); 00129 } 00130 // check if this function is implemented at all: 00131 if ( ADEM == 0x00 ) { 00132 return false; 00133 } 00134 return true; 00135 } 00136 00137 void HAL::VMEConfigurationSpaceHandler::checkVME64xConfigSpace( uint32_t slot ) const 00138 throw( HAL::IllegalOperationException ) { 00139 if ( ! containsVME64xModule( slot ) ) { 00140 std::stringstream text; 00141 text << "There is no VME64x Module in slot" << std::dec << slot 00142 << "\n (HAL::VMEConfigurationSpaceHandler::checkVME64xConfigSpace)" 00143 << std::ends; 00144 throw( HAL::IllegalOperationException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) ); 00145 } 00146 } 00147 00148 uint32_t HAL::VMEConfigurationSpaceHandler::getUserROMInterval( uint32_t slot ) const { 00149 uint32_t byteInterval, romWidth; 00150 saveRead( "CRWidth", slot, &romWidth ); 00151 if ( romWidth == 0x81 ) { 00152 byteInterval = 4; 00153 } else if( romWidth == 0x82 ) { 00154 byteInterval = 2; 00155 } else { 00156 byteInterval = 1; 00157 } 00158 return byteInterval; 00159 }; 00160 00161 void HAL::VMEConfigurationSpaceHandler::readROMBlock( uint32_t slot, 00162 uint32_t startAdr, 00163 uint32_t endAdr, 00164 std::vector<unsigned char>* data ) const { 00165 // The configuration region which is valid for readout is given by the 00166 // field "Configuration ROM data access width". The value of this field 00167 // determines which bytes are considered during the checksum building. 00168 // The region above 0x1000 is the User region. Which bytes are used is 00169 // specified in the field "Configuration ROM data access width". 00170 // 00171 // In the specified part of the ROM only every 4th byte is valid and has 00172 // to be taken into account when building the checksum. But modules must 00173 // deliver 00 on bytes which are not defined. Therefore the checksum does 00174 // not change if these bytes are also taken in consideration while building 00175 // the checksum. 00176 uint32_t ic, offset, readData; 00177 uint32_t userROMInterval = getUserROMInterval( slot ); 00178 00179 // it must be considered that the area up to 0xfff is only every 4th byte. 00180 for ( ic=0, offset = startAdr; offset <= endAdr; ic++, offset += userROMInterval ) { 00181 saveRead( "romStart", slot, &readData, offset ); 00182 data->push_back((unsigned char)readData); 00183 } 00184 } 00185 00186 00187 bool HAL::VMEConfigurationSpaceHandler::checksumOk( uint32_t slot ) const 00188 throw( HAL::IllegalOperationException ) { 00189 checkVME64xConfigSpace( slot ); 00190 uint32_t romLength; 00191 saveRead( "romLength", slot, &romLength ); 00192 uint32_t userROMInterval = getUserROMInterval( slot ); 00193 std::vector<unsigned char> CRRom; 00194 uint32_t endAdr = userROMInterval * (romLength - 1) + 7; 00195 readROMBlock( slot, 0x07, endAdr, &CRRom ); 00196 // build checksum 00197 uint32_t checksum = 0; 00198 for ( uint32_t ic=0; ic<romLength; ic++ ) { 00199 checksum += (uint32_t)CRRom[ic]; 00200 } 00201 00202 // now the spec is not clear...what the hell should be an 00203 // eight bit 2s complement binary checksum ???? Probably they 00204 // want a 2s complement of the checksum in order to be able 00205 // to add it to the checksum and test for 0. 00206 checksum &= 0x00ff; 00207 uint32_t romChecksum; 00208 saveRead( "checksum", slot, &romChecksum ); 00209 return ( (0xff & (checksum + romChecksum)) == 0); 00210 } 00211 00212 std::string HAL::VMEConfigurationSpaceHandler::readSerialNumber( uint32_t slot ) const 00213 throw( HAL::IllegalOperationException ) { 00214 00215 checkVME64xConfigSpace( slot ); 00216 uint32_t size, startAdr, endAdr, userROMInterval; 00217 saveRead( "serialNumberStart", slot, &startAdr ); 00218 saveRead( "serialNumberEnd", slot, &endAdr ); 00219 userROMInterval = getUserROMInterval( slot ); 00220 size = (endAdr - startAdr + userROMInterval) / userROMInterval; 00221 std::vector<unsigned char> serialChar; 00222 readROMBlock( slot, startAdr, endAdr, &serialChar ); 00223 size = serialChar.size(); 00224 char chararr[ size + 1 ]; 00225 for ( uint32_t ic = 0; ic < size; ic++ ) { 00226 chararr[ic] = serialChar[ic]; 00227 } 00228 chararr [ size ] = (char)0x00; 00229 std::string result( (char*)chararr ); 00230 return result; 00231 } 00232 00233 void HAL::VMEConfigurationSpaceHandler::enableVME64xModule( uint32_t slotId ) const 00234 throw( HAL::IllegalOperationException ) { 00235 checkVME64xConfigSpace( slotId ); 00236 saveWrite( "bitSet", slotId, 0x10 ); 00237 } 00238 00239 void HAL::VMEConfigurationSpaceHandler::disableVME64xModule( uint32_t slotId ) const 00240 throw( HAL::IllegalOperationException ) { 00241 checkVME64xConfigSpace( slotId ); 00242 saveWrite( "bitClear", slotId, 0x10 ); 00243 } 00244 00245 bool HAL::VMEConfigurationSpaceHandler::enabled( uint32_t slotId ) const 00246 throw( HAL::IllegalOperationException ) { 00247 checkVME64xConfigSpace( slotId ); 00248 uint32_t result; 00249 saveRead( "bitSet", slotId, &result); 00250 return ( (result & 0x10) == 0x10 ); 00251 } 00252 00253 HAL::VMEBusAdapterInterface& HAL::VMEConfigurationSpaceHandler::getBusAdapter() const { 00254 return busAdapter_; 00255 }