Generic hardware access library
|
00001 #include "hal/VMEDevice.hh" 00002 00003 #include <string> 00004 #include <sstream> 00005 #include <iomanip> 00006 00007 HAL::VMEDevice::VMEDevice( HAL::VMEAddressTable & vmeAddressTable, 00008 HAL::VMEBusAdapterInterface & vmeBusAdapter, 00009 uint32_t baseaddress, 00010 bool doSwapping ) 00011 throw( HAL::BusAdapterException, 00012 HAL::UnsupportedException ) 00013 : HAL::HardwareDevice( vmeAddressTable ), 00014 vmeBusAdapter(vmeBusAdapter), 00015 baseaddresses_( NUMBER_OF_VME64XFUNCTIONS ), 00016 doSwapping_( doSwapping ) { 00017 00018 // default : put the baseaddress into the first function baseaddress 00019 // this might be overwritten by the busadapter in case it is doing some 00020 // memory mapping. 00021 baseaddresses_[0] = baseaddress; 00022 vmeBusAdapter.openDevice(vmeAddressTable, 00023 baseaddress, 00024 &deviceIdentifierPtr, 00025 &(baseaddresses_[0]), 00026 doSwapping_); 00027 } 00028 00029 // the constructore for VME64x modules 00030 HAL::VMEDevice::VMEDevice( HAL::VMEAddressTable & vmeAddressTable, 00031 HAL::VMEBusAdapterInterface & vmeBusAdapter, 00032 std::vector<uint32_t>& baseaddresses, 00033 bool doSwapping ) 00034 throw( HAL::BusAdapterException, 00035 HAL::IllegalValueException, 00036 HAL::UnsupportedException ) 00037 : HAL::HardwareDevice( vmeAddressTable ), 00038 vmeBusAdapter(vmeBusAdapter), 00039 baseaddresses_( baseaddresses ), 00040 doSwapping_( doSwapping ) { 00041 00042 // check if we got a correct baseaddress vector, otherwise things might 00043 // go horribly wrong in the openDevice call which assumes that we have 00044 // really space for 8 baseaddresses in the vector! 00045 if ( baseaddresses_.size() != NUMBER_OF_VME64XFUNCTIONS ) { 00046 std::stringstream text; 00047 text << "baseaddress-vector does not have exactly size " << NUMBER_OF_VME64XFUNCTIONS << "!" 00048 << "\n (HAL::VMEDevice::VMEDevice)" << std::ends; 00049 throw( HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) ); 00050 } 00051 00052 vmeBusAdapter.openDevice(vmeAddressTable, 00053 baseaddresses, 00054 &deviceIdentifierPtr, 00055 &(baseaddresses_), 00056 doSwapping_); 00057 } 00058 00059 HAL::VMEDevice::~VMEDevice() { 00060 vmeBusAdapter.closeDevice( deviceIdentifierPtr ); 00061 } 00062 00063 void HAL::VMEDevice::hardwareRead( const HAL::GeneralHardwareAddress& vmeAddress, 00064 uint32_t* result, 00065 uint32_t offset ) const 00066 throw( HAL::BusAdapterException ) { 00067 00068 vmeBusAdapter.read( deviceIdentifierPtr, 00069 vmeAddress.getComputedAddress( baseaddresses_ ) + offset, 00070 vmeAddress.getAddressModifier(), 00071 vmeAddress.getDataWidth(), 00072 result ); 00073 } 00074 00075 void HAL::VMEDevice::hardwareWrite( const HAL::GeneralHardwareAddress& vmeAddress, 00076 uint32_t data, 00077 uint32_t offset ) const 00078 throw( HAL::BusAdapterException ) { 00079 00080 vmeBusAdapter.write( deviceIdentifierPtr, 00081 vmeAddress.getComputedAddress( baseaddresses_ ) + offset, 00082 vmeAddress.getAddressModifier(), 00083 vmeAddress.getDataWidth(), 00084 data); 00085 } 00086 00087 void HAL::VMEDevice::hardwareReadBlock( const HAL::GeneralHardwareAddress& vmeAddress, 00088 uint32_t length, 00089 char *buffer, 00090 HalAddressIncrement addressBehaviour, 00091 uint32_t offset) const 00092 throw ( HAL::IllegalValueException, 00093 HAL::BusAdapterException, 00094 HAL::UnsupportedException ) { 00095 00096 uint32_t dataWidth = vmeAddress.getDataWidth(); 00097 if ( length%dataWidth != 0 ) { 00098 std::string text = "the length is not a multiple of the dataWidth!\n (HAL::VMEDevice::readBlock)"; 00099 throw( HAL::IllegalValueException( text, __FILE__, __LINE__, __FUNCTION__ ) ); 00100 } 00101 uint32_t startAddress = vmeAddress.getComputedAddress( baseaddresses_ ) + offset; 00102 if ( (startAddress) % dataWidth != 0 ) { 00103 std::stringstream text ; 00104 text << "the startaddress must be aligned for dataWidth " 00105 << std::dec << dataWidth << ".\n" 00106 << " But the start address is " 00107 << std::hex << std::setw(8) << std::setfill('0') << startAddress 00108 << "\n (this is not necessarily an address which you can easily derive because\n" 00109 << " it depends on the BusAdapter implementation)\n" 00110 << " (HAL::VMEDevice::readBlock)" << std::ends; 00111 throw( HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) ); 00112 } 00113 vmeBusAdapter.readBlock( deviceIdentifierPtr, 00114 startAddress, 00115 length, 00116 vmeAddress.getAddressModifier(), 00117 dataWidth, 00118 buffer, 00119 addressBehaviour); 00120 } 00121 00122 void HAL::VMEDevice::hardwareWriteBlock( const HAL::GeneralHardwareAddress& vmeAddress, 00123 uint32_t length, 00124 char *buffer, 00125 HalAddressIncrement addressBehaviour, 00126 uint32_t offset) const 00127 throw ( HAL::IllegalValueException, 00128 HAL::BusAdapterException, 00129 HAL::UnsupportedException ) { 00130 00131 uint32_t dataWidth = vmeAddress.getDataWidth(); 00132 if ( (length) % dataWidth != 0 ) { 00133 std::string text = "the length is not a multiple of the dataWidth!\n (HAL::VMEDevice::writeBlock)"; 00134 throw( HAL::IllegalValueException( text, __FILE__, __LINE__, __FUNCTION__ ) ); 00135 } 00136 uint32_t startAddress = vmeAddress.getComputedAddress( baseaddresses_ ) + offset; 00137 if ( (startAddress) % dataWidth != 0 ) { 00138 std::stringstream text; 00139 text << "the startaddress must be aligned for dataWidth " 00140 << std::dec << dataWidth << ".\n" 00141 << " But the start address is " 00142 << std::hex << std::setw(8) << std::setfill('0') << startAddress 00143 << "\n (this is not necessarily an address which you can easily derive because\n" 00144 << " it depends on the BusAdapter implementation)\n" 00145 << " (HAL::VMEDevice::writeBlock)" << std::ends; 00146 throw( HAL::IllegalValueException( text.str(), __FILE__, __LINE__, __FUNCTION__ ) ); 00147 } 00148 vmeBusAdapter.writeBlock( deviceIdentifierPtr, 00149 startAddress, 00150 length, 00151 vmeAddress.getAddressModifier(), 00152 dataWidth, 00153 buffer, 00154 addressBehaviour); 00155 }