Generic hardware access library
/home/cschwick/hal/generic/src/common/VMEDevice.cc
Go to the documentation of this file.
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 }