Library of Bus-Adapters
/home/cschwick/hal/busAdapter/dummy/src/common/VMEDummyBusAdapter.cc
Go to the documentation of this file.
00001 #include "hal/VMEDummyBusAdapter.hh"
00002 #include <iomanip>
00003 #include <iostream>
00004 #include <string.h>
00005 
00006 // dirty but ok...:
00007 typedef unsigned short U16;
00008 typedef uint32_t U32;
00009 
00010 HAL::VMEDummyBusAdapter::VMEDummyBusAdapter( enum VerboseMode verbose, 
00011                                         enum MemoryMode  memoryMode,
00012                                         std::ostream& os )
00013     : os_( os ) {
00014     deviceNumberCounter = 0;
00015     this->verbose = verbose;
00016     this->memoryMode = memoryMode;
00017     os_  << "VMEDummyBusAdapter : constructor has been called :\n" 
00018          << "                     The \"verbose\" flag is set to " << (int)verbose << "\n"
00019          << "                     The \"memoryMode\" flag is set to " << (int)memoryMode  
00020          << std::endl;
00021 }
00022 
00023 HAL::VMEDummyBusAdapter::~VMEDummyBusAdapter() {
00024     os_  << "VMEDummyBusAdapter : destructor called" << std::endl;
00025 }
00026 
00027 void
00028 HAL::VMEDummyBusAdapter::openDevice(const VMEAddressTable& vmeAddressTable,
00029                                uint32_t vmeBaseaddress,
00030                                DeviceIdentifier** deviceIdentifierPtr,
00031                                uint32_t* baseAddressPtr,
00032                                bool doSwapping ) 
00033     throw() {
00034     std::vector<char *> memoryRegions(NUMBER_OF_VME64XFUNCTIONS);
00035     for ( int i=0; i<NUMBER_OF_VME64XFUNCTIONS; i++ ) memoryRegions.push_back( (char*) 0 );
00036 
00037     uint32_t ic;
00038     os_  << "VMEDummyBusAdapter : opening Device number "<< deviceNumberCounter 
00039          << " with baseAddress : " 
00040          << std::hex << std::setw(8) << std::setfill('0') << vmeBaseaddress
00041          << "\n                     memory-mapping-mode : "
00042          << (int)this->memoryMode 
00043          << std::endl;
00044 
00045     std::vector<uint32_t> minAddresses(NUMBER_OF_VME64XFUNCTIONS); 
00046     std::vector<uint32_t> maxAddresses(NUMBER_OF_VME64XFUNCTIONS);
00047     std::vector<uint32_t> baseAddresses(NUMBER_OF_VME64XFUNCTIONS);
00048     std::vector<uint32_t> mapSizes(NUMBER_OF_VME64XFUNCTIONS);
00049 
00050     for ( int i=0; i<NUMBER_OF_VME64XFUNCTIONS; i++ ) {
00051       minAddresses[i] = 0;
00052       maxAddresses[i] = 0;
00053       baseAddresses[i] = 0;
00054       mapSizes[i] = 0;
00055     }
00056 
00057     if ( memoryMode == MEMORY_MAP_ON ) {
00058 
00059         vmeAddressTable.getAddressBoundaries( minAddresses, maxAddresses );
00060 
00061         *baseAddressPtr = vmeBaseaddress;
00062 
00063         // it is assumed that the mapped region starts at an item which corresponds
00064         // to an AddressTable entry at '0'.
00065         uint32_t nbytes = maxAddresses[0] + 1;
00066 
00067         memoryRegions[0] = new char[ nbytes ];
00068         baseAddresses[0] = vmeBaseaddress;
00069         mapSizes[0]      = nbytes;
00070 
00071         for (ic=0; ic<=maxAddresses[0]; ic++) memoryRegions[0][ic] = (char)0x00;
00072 
00073         os_  << "                     mapped the address space to memory address " 
00074              << std::hex << memoryRegions[0] 
00075              << "\n                     reserved 0x" << std::hex << nbytes
00076              << " (dec: " << std::dec << nbytes << " )" 
00077              << " bytes for memory mapped operation" << std::endl; 
00078     } else {
00079         *baseAddressPtr = vmeBaseaddress;
00080     }
00081 
00082     *deviceIdentifierPtr = new HAL::VMEDummyDeviceIdentifier( deviceNumberCounter,
00083                                                               memoryRegions,
00084                                                               baseAddresses,
00085                                                               mapSizes,
00086                                                               doSwapping );
00087     deviceNumberCounter++;
00088 }
00089 
00090 // the call for VME64x modules
00091 void
00092 HAL::VMEDummyBusAdapter::openDevice( const VMEAddressTable& vmeAddressTable,
00093                                      std::vector<uint32_t>& vmeBaseaddresses,
00094                                      DeviceIdentifier** deviceIdentifierPtr,
00095                                      std::vector<uint32_t>* baseAddressPtr,
00096                                      bool doSwapping ) 
00097     throw() {
00098     std::vector<char *> memoryRegions(NUMBER_OF_VME64XFUNCTIONS);
00099     for ( int i=0; i<NUMBER_OF_VME64XFUNCTIONS; i++ ) memoryRegions.push_back( (char*) 0 );
00100 
00101     uint32_t ic;
00102     os_  << "VMEDummyBusAdapter : opening VME64x Device number "<< deviceNumberCounter 
00103          << "\n                     memory-mapping-mode : "
00104          << (int)this->memoryMode 
00105          << std::endl;
00106 
00107     std::vector<uint32_t> minAddresses(NUMBER_OF_VME64XFUNCTIONS); 
00108     std::vector<uint32_t> maxAddresses(NUMBER_OF_VME64XFUNCTIONS);
00109     std::vector<uint32_t> baseAddresses(NUMBER_OF_VME64XFUNCTIONS);
00110     std::vector<uint32_t> mapSizes(NUMBER_OF_VME64XFUNCTIONS);
00111 
00112     for ( int i=0; i<NUMBER_OF_VME64XFUNCTIONS; i++ ) {
00113       minAddresses[i] = 0;
00114       maxAddresses[i] = 0;
00115       baseAddresses[i] = 0;
00116       mapSizes[i] = 0;
00117     }
00118 
00119     if ( memoryMode == MEMORY_MAP_ON ) {
00120 
00121         vmeAddressTable.getAddressBoundaries( minAddresses, maxAddresses );
00122 
00123         for ( int ifunc=0; ifunc<NUMBER_OF_VME64XFUNCTIONS; ifunc++ ) {
00124 
00125             if ( maxAddresses[ifunc] > 0 ) {
00126 
00127                 (*baseAddressPtr)[ifunc] = vmeBaseaddresses[ifunc];
00128                 
00129                 // it is assumed that the mapped region starts at an item which corresponds
00130                 // to an AddressTable entry at '0'.
00131                 uint32_t nbytes = maxAddresses[ifunc] + 1;
00132                 
00133                 memoryRegions[ifunc] = new char[ nbytes ];
00134                 baseAddresses[ifunc] = vmeBaseaddresses[ifunc];
00135                 mapSizes[ifunc]      = nbytes;
00136 
00137                 for (ic=0; ic<maxAddresses[ifunc]; ic++) memoryRegions[ifunc][ic] = (char)0x00;
00138         
00139                 os_  << "                     mapped the address space of function" << ifunc 
00140                      << " to memory address " << std::hex << (memoryRegions[ifunc]) 
00141                      << "\n                     reserved 0x" << std::hex << nbytes
00142                      << " (dec: " << std::dec << nbytes << " )" 
00143                      << " bytes for memory mapped operation" << std::endl;
00144             } 
00145         }
00146     } else {
00147         for ( int ifunc=0; ifunc<NUMBER_OF_VME64XFUNCTIONS; ifunc++ ) {
00148             (*baseAddressPtr)[ifunc] = vmeBaseaddresses[ifunc];
00149         }
00150     }
00151 
00152     *deviceIdentifierPtr = new HAL::VMEDummyDeviceIdentifier( deviceNumberCounter,
00153                                                               memoryRegions,
00154                                                               baseAddresses,
00155                                                               mapSizes,
00156                                                               doSwapping );
00157     deviceNumberCounter++;
00158 }
00159 
00160 void
00161 HAL::VMEDummyBusAdapter::closeDevice( DeviceIdentifier* vmeDevice ) 
00162     throw() {
00163     os_  << "VMEDummyBusAdapter : closing Device  \n" 
00164          << "                     " << vmeDevice->printString() << std::endl;
00165     delete( vmeDevice );
00166 }
00167 
00168 void
00169 HAL::VMEDummyBusAdapter::read( DeviceIdentifier* vmeDevice, 
00170                           uint32_t address,
00171                           uint32_t addressModifier,
00172                           uint32_t dataWidth,
00173                           uint32_t *resultPtr ) 
00174     throw() {
00175 
00176     *resultPtr = 0;
00177     if ( memoryMode == MEMORY_MAP_ON ) {
00178 
00179         char *memoryAddress = dynamic_cast<HAL::VMEDummyDeviceIdentifier*>(vmeDevice)->remap( address );
00180         
00181         memcpy( resultPtr, memoryAddress, dataWidth);
00182         
00183         bool doSwapping = dynamic_cast<HAL::VMEDummyDeviceIdentifier*>(vmeDevice)->doSwapping();
00184         
00185         if ( dataWidth > 1 && doSwapping ) {
00186             *resultPtr = doSwap( *resultPtr, dataWidth );
00187         }
00188         
00189     }
00190 
00191     if ( verbose == VERBOSE_ON ) {
00192         os_  << std::endl;
00193         os_  << "VMEDummyBusAdapter : read from Device number " << vmeDevice->printString() << std::endl;
00194         os_  << "                     address : " << std::hex << std::setw(8) << std::setfill('0') << address << std::endl;
00195         os_  << "                          AM :       " << std::hex << std::setw(2) << std::setfill('0') << addressModifier << std::endl;
00196         os_  << "                   dataWidth : " << std::dec << std::setw(8) << std::setfill(' ') << dataWidth << std::endl;
00197         os_  << "                   returning : 0x" << std::hex << std::setw(8) << std::setfill('0') << *resultPtr 
00198              << " (dec) " << std::dec << *resultPtr << std::endl;
00199         os_  << std::endl;
00200     }
00201 }
00202 
00203 void
00204 HAL::VMEDummyBusAdapter::write( DeviceIdentifier* vmeDevice, 
00205                            uint32_t address, 
00206                            uint32_t addressModifier,
00207                            uint32_t dataWidth,
00208                            uint32_t data) 
00209     throw() {
00210 
00211     bool doSwapping = dynamic_cast<HAL::VMEDummyDeviceIdentifier*>(vmeDevice)->doSwapping();
00212 
00213     if ( dataWidth > 1 && doSwapping ) {
00214         data = doSwap( data, dataWidth );
00215     }
00216 
00217     if ( memoryMode == MEMORY_MAP_ON ) {
00218 
00219         char *memoryAddress = dynamic_cast<HAL::VMEDummyDeviceIdentifier*>(vmeDevice)->remap( address );
00220         memcpy( memoryAddress, &data, dataWidth);
00221 
00222     }
00223 
00224     if ( verbose == VERBOSE_ON ) {
00225         os_  << std::endl;
00226         os_  << "VMEDummyBusAdapter : write to Device number " << vmeDevice->printString() << std::endl;
00227         os_  << "                     address : " << std::hex << std::setw(8) << std::setfill('0') << address << std::endl;
00228         os_  << "                          AM :       " << std::hex << std::setw(2) << std::setfill(' ') << addressModifier << std::endl;
00229         os_  << "                   dataWidth : " << std::dec << std::setw(8) << std::setfill(' ') << dataWidth << std::endl;
00230         os_  << "                   dataValue : 0x" << std::hex << std::setw(8) << std::setfill('0') << data 
00231              << " (dec) " << std::dec << data << std::endl;
00232         os_  << std::endl;
00233     }
00234 }
00235 
00236 uint32_t HAL::VMEDummyBusAdapter::doSwap( uint32_t data, uint32_t dataWidth ) const {
00237     uint32_t result = 0;
00238     if ( dataWidth == 2 ) {
00239         result = ((data & 0xff) << 8) +
00240             ((data & 0xff00) >> 8);
00241 
00242     } else if ( dataWidth == 4 ) {
00243         result = ((data & 0xff) << 24) +
00244             ((data & 0xff00) << 8 ) +
00245             ((data & 0xff0000) >> 8) +
00246             ((data & 0xff000000) >> 24);
00247     } else {
00248         os_ << "HAL Software bug: dataWidth " << std::dec << dataWidth << "is illegal!" << std::endl;
00249     }  
00250     return result;
00251 }
00252 
00253 void
00254 HAL::VMEDummyBusAdapter::resetBus( ) 
00255     throw() {
00256     if ( verbose == VERBOSE_ON ) {
00257         os_  << std::endl;
00258         os_  << "VMEDummyBusAdapter : resetting bus" << std::endl;
00259         os_  << std::endl;
00260     }
00261 }
00262 
00263 void
00264 HAL::VMEDummyBusAdapter::readBlock( DeviceIdentifier *vmeDevice,
00265                                uint32_t startAddress,
00266                                uint32_t length,      // in bytes
00267                                uint32_t addressModifier,
00268                                uint32_t dataWidth,
00269                                char *buffer,
00270                                HalAddressIncrement addressBehaviour ) 
00271     throw() {
00272 
00273     if ( memoryMode == MEMORY_MAP_ON ) {
00274         char *memoryAddress = dynamic_cast<HAL::VMEDummyDeviceIdentifier*>(vmeDevice)->remap( startAddress );
00275         if ( addressBehaviour == HAL_DO_INCREMENT ) {
00276             memcpy( buffer, memoryAddress, length);
00277         } else {
00278             os_  << "HAL::VMEDummyBusAdapter::readBlock : No Fifo functionality in VMEDummyBusAdapter. Doing nothing!" << std::endl;
00279         }
00280 
00281         // check if data needs to be swapped and swap it
00282         bool doSwapping = dynamic_cast<HAL::VMEDummyDeviceIdentifier*>(vmeDevice)->doSwapping();
00283         
00284         if ( dataWidth > 1 && doSwapping ) {
00285             if ( dataWidth == 2 ) {
00286                 for ( U16* ptr = (U16*)buffer; (uint8_t*) ptr < (uint8_t*) buffer + length; ptr++ ) {
00287                     *ptr = doSwap( *ptr, dataWidth );
00288                 }
00289             } else if ( dataWidth == 4 ) {
00290                 for ( U32* ptr = (U32*)buffer; (uint8_t*) ptr < (uint8_t*) buffer + length; ptr++ ) {
00291                     *ptr = doSwap( *ptr, dataWidth );
00292                 }
00293             } else {
00294                 os_ << "HAL Software bug: dataWidth " << std::dec << dataWidth << "is illegal!" << std::endl;
00295             }
00296         }
00297         
00298     }
00299 
00300  
00301 
00302     if( verbose == VERBOSE_ON ) {
00303         os_  << std::endl;
00304         os_  << "VMEDummyBusAdapter : readBlock from Device \n                     " << vmeDevice->printString() << std::endl;
00305         os_  << "                startaddress (hex) : " << std::hex << std::setw(8) << std::setfill('0') << startAddress << std::endl;
00306         os_  << "                      length (hex) : " << std::hex << std::setw(8) << std::setfill('0') << length << std::endl;
00307         os_  << "                          AM (hex) :       " << std::hex << std::setw(2) << std::setfill('0') << addressModifier << std::endl;
00308         os_  << "                         dataWidth : " << std::dec << std::setw(8) << std::setfill(' ') << dataWidth << std::endl;
00309         os_  << "                  addressBehaviour : ";
00310         if ( addressBehaviour == HAL_DO_INCREMENT ) {
00311             os_  << "HAL_DO_INCREMENT" << std::endl;
00312         } else if ( addressBehaviour == HAL_NO_INCREMENT ) {
00313             os_  << "HAL_NO_INCREMENT" << std::endl;
00314         } else { // should never happen
00315             os_  << "XXXXXXXXXXXXXXXX" << std::endl;
00316         }
00317         os_  << "       pointer to readbuffer (hex) : " << std::hex << std::setw(8) << std::setfill('0') << buffer << std::endl;
00318         os_  << std::endl;
00319     }
00320 }
00321   
00322 void
00323 HAL::VMEDummyBusAdapter::writeBlock( DeviceIdentifier* vmeDevice,
00324                                 uint32_t startAddress,
00325                                 uint32_t length,      // in bytes
00326                                 uint32_t addressModifier,
00327                                 uint32_t dataWidth,
00328                                 char *buffer,
00329                                 HalAddressIncrement addressBehaviour ) 
00330     throw() {
00331   
00332 
00333     if ( memoryMode == MEMORY_MAP_ON ) {
00334         // check if data needs to be swapped and swap it
00335         bool doSwapping = dynamic_cast<HAL::VMEDummyDeviceIdentifier*>(vmeDevice)->doSwapping();
00336         char* buffercpy = new char[length];
00337         memcpy( buffercpy, buffer, length );
00338 
00339         if ( dataWidth > 1 && doSwapping ) {
00340             if ( dataWidth == 2 ) {
00341                 for ( U16* ptr = (U16*)buffercpy; (uint8_t*) ptr < (uint8_t*) buffercpy + length; ptr++ ) {
00342                     *ptr = doSwap( *ptr, dataWidth );
00343                 }
00344             } else if ( dataWidth == 4 ) {
00345                 for ( U32* ptr = (U32*)buffercpy; (uint8_t*) ptr < (uint8_t*) buffercpy + length; ptr++ ) {
00346                     *ptr = doSwap( *ptr, dataWidth );
00347                 }
00348             } else {
00349                 os_ << "HAL Software bug: dataWidth " << std::dec << dataWidth << "is illegal!" << std::endl;
00350             }
00351         }
00352         
00353         char *memoryAddress = dynamic_cast<HAL::VMEDummyDeviceIdentifier*>(vmeDevice)->remap( startAddress );
00354 
00355         if ( addressBehaviour == HAL_DO_INCREMENT ) {
00356             memcpy( memoryAddress, buffercpy, length);
00357         } else {
00358             os_  << "HAL::VMEDummyBusAdapter::writeBlock : No Fifo functionality in VMEDummyBusAdapter. Doing nothing!" << std::endl;
00359         }
00360         
00361         delete buffercpy;
00362 
00363     }
00364 
00365     if ( verbose == VERBOSE_ON ) {
00366         os_  << std::endl;
00367         os_  << "VMEDummyBusAdapter : writeBlock to Device \n                     " << vmeDevice->printString() << std::endl;
00368         os_  << "                startaddress (hex) : " << std::hex << std::setw(8) << std::setfill('0') << startAddress << std::endl;
00369         os_  << "                      length (hex) : " << std::hex << std::setw(8) << std::setfill('0') << length << std::endl;
00370         os_  << "                          AM (hex) :       " << std::hex << std::setw(2) << std::setfill('0') << addressModifier << std::endl;
00371         os_  << "                         dataWidth : " << std::dec << std::setw(8) << std::setfill(' ') << dataWidth << std::endl;
00372         os_  << "                  addressBehaviour : ";
00373         if ( addressBehaviour == HAL_DO_INCREMENT ) {
00374             os_  << "HAL_DO_INCREMENT" << std::endl;
00375         } else if ( addressBehaviour == HAL_NO_INCREMENT ) {
00376             os_  << "HAL_NO_INCREMENT" << std::endl;
00377         } else { // should never happen
00378             os_  << "XXXXXXXXXXXXXXXX" << std::endl;
00379         }
00380         os_  << "     pointer to sourcebuffer (hex) : " << std::hex << std::setw(8) << std::setfill('0') << buffer << std::endl;
00381         os_  << std::endl;
00382     }
00383 }