Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Related Pages

SctApiBlock.cxx

00001 
00009 #include <iostream>
00010 
00011 #include <boost/lexical_cast.hpp>
00012 
00013 #include "Sct/Env.h"
00014 
00015 #include "SctApi.h"
00016 #include "SctApiDebug.h"
00017 #include "crate.h"
00018 #include "utility.h"
00019 
00020 #include "primListWrapper.h"
00021 #include "PrimBuilder.h"
00022 
00023 #include "VmeDecode.h"
00024 
00025 // For exceptions
00026 #include "RodCrate/RodModule.h"
00027 
00028 using namespace std;
00029 using namespace SctPixelRod;
00030 using namespace boost;
00031 using namespace SctApi::Utility;
00032 
00033 namespace SctApi {
00034 #warning "Should some of these return smart pointers?"
00035 
00036 /*
00037   Dump contents of a block of DSP memory to cout.
00038   Use dspNumber -1 to refer to the master DSP.
00039 */
00040 int SctApi::dspBlockDump(unsigned int partition, unsigned int crate, unsigned int rod,
00041                          long dspStart, long numWords, long dspNumber, bool usePrim) {
00042   {
00043     boost::mutex::scoped_lock lock(logMutex);
00044     log << "DspBlockDump (" << partition << " " << crate << " " << rod << ") "
00045         << dspStart << " " << numWords << " " << dspNumber << endl;
00046   }
00047 
00048   // read data
00049   unsigned long length;
00050   unsigned long *buffer = dspBlockRead(partition, crate, rod, dspStart, numWords, dspNumber, length, usePrim);
00051 
00052   if(!buffer) {
00053     // Something didn't work
00054     return 1;
00055   }
00056 
00057   printMemoryBlock(cout, buffer, numWords, 8, 0);
00058 
00059   char *name = tempnam("./", "textB");
00060   if(checkDebugOption(DEBUG_DIAG))
00061     cout << "Write output to " << name << endl;
00062   ofstream output(name);
00063   free(name);
00064 
00065   output.write((char *)buffer, numWords * 4);
00066  
00067   delete [] buffer;
00068 
00069   return 0;
00070 }
00071 
00072 /*
00073   Dump contents of a block of DSP memory to a file.
00074   Use dspNumber -1 to refer to the master DSP.
00075 */
00076 int SctApi::dspBlockDumpFile(unsigned int partition, unsigned int crate, unsigned int rod,
00077                              long dspStart, long numWords, long dspNumber, string filename, bool usePrim){
00078   {
00079     boost::mutex::scoped_lock lock(logMutex);
00080     log << "DspBlockDumpFile (" << partition << " " << crate << " " << rod << ") "
00081         << hex << "0x" << dspStart << hex << " " << numWords << " " << dspNumber << " to " << filename << endl;
00082   }
00083 
00084   unsigned long length;
00085   unsigned long * buffer = dspBlockRead(partition, crate, rod, dspStart, numWords, dspNumber, length, usePrim);
00086 
00087   if(buffer) {
00088     if(checkDebugOption(DEBUG_DIAG2)) 
00089       cout << "Writing output to " << filename << endl;
00090     ofstream output(filename.c_str());
00091 
00092     output.write((char *)buffer, numWords * 4);
00093 
00094     // delete the buffer
00095     delete [] buffer;
00096   } else {
00097     cout << "Block read failed!\n";
00098     return 1;
00099   }
00100 
00101   return 0;
00102 }
00103 
00104 /*
00105   Read contents of a block of DSP memory 
00106 
00107   Use dspNumber -1 to refer to the master DSP.
00108 */
00109 unsigned long *SctApi::dspBlockRead(unsigned int partition, unsigned int crate, unsigned int rod,
00110                                     long dspStart, long numWords, long dspNumber, unsigned long &length, bool usePrim){
00111   {
00112     boost::mutex::scoped_lock lock(logMutex);
00113     log << "DspBlockRead (" << partition << " " << crate << " " << rod << ") "
00114         << hex << "0x" << dspStart << dec << " " << numWords << " " << dspNumber << endl << flush;
00115   }
00116   Crate* myCrate = getCrate(partition, crate);
00117 
00118   if(!myCrate) {
00119     cout << "Request for non-existent crate " << partition << " " << crate << endl;
00120     return 0;
00121   }
00122 
00123   if(dspNumber < -1 || dspNumber > 3) {
00124     cout << "dspBlockRead slave out of range " << dspNumber << endl;
00125     throw SctApiException("DspBlockRead slave out of range");
00126   }
00127 
00128   // create buffer
00129   unsigned long * buffer = new unsigned long[numWords];
00130 
00131   for(int i=0; i<numWords; i++) {
00132     buffer[i] = 0;
00133   }
00134 
00135   // read data
00136   if (dspNumber == -1) {
00137     if(checkDebugOption(DEBUG_DIAG2))
00138       cout << "Reading from mdsp\n";
00139     myCrate->mdspBlockRead(rod, dspStart, buffer, numWords);
00140   } else {
00141     if(checkDebugOption(DEBUG_DIAG2))
00142       cout << "Reading from dsp " << dspNumber << endl;
00143 
00144     if(usePrim) {
00145       delete [] buffer;
00146       buffer = primReadSlaveDsp(partition, crate, rod, dspNumber, dspStart, numWords);
00147     } else {
00148       myCrate->slvBlockRead(rod, dspStart, buffer, numWords, dspNumber);
00149     }
00150   }
00151 
00152   length = numWords;
00153 
00154   // Don't delete the buffer!!!
00155   return buffer;
00156 }
00157 
00158 int SctApi::dspBlockWrite(unsigned int partition, unsigned int crate, unsigned int rod,
00159                           unsigned long *buffer, unsigned long dspAddress, long numWords, 
00160                           long dspNumber, bool usePrim){
00161   {
00162     boost::mutex::scoped_lock lock(logMutex);
00163     log << "DspBlockWrite (" << partition << " " << crate << " " << rod << ") "
00164         << dspAddress << " " << numWords << " " << dspNumber << endl << flush;
00165   }
00166 
00167   Crate* myCrate = getCrate(partition, crate);
00168 
00169   if(!myCrate) {
00170     cout << "Request for non-existent crate " << partition << " " << crate << endl;
00171     return 0;
00172   }
00173 
00174   // Write data
00175   if (dspNumber == -1) {
00176     if(checkDebugOption(DEBUG_DIAG))
00177       cout << "Writing to mdsp\n";
00178     myCrate->mdspBlockWrite(rod, dspAddress, buffer, numWords);
00179   } else {
00180     if(checkDebugOption(DEBUG_DIAG))
00181       cout << "Writing to dsp " << dspNumber << endl;
00182     if(usePrim) {
00183       primWriteSlaveDsp(partition, crate, rod, dspNumber, dspAddress, numWords, buffer);
00184     } else {
00185       myCrate->slvBlockWrite(rod, dspAddress, buffer, numWords, dspNumber);
00186     }
00187   }
00188 
00189   return 0;
00190 }
00191 
00192 unsigned long SctApi::dspSingleBlockRead(unsigned int partition, unsigned int crate, unsigned int rod,
00193                                          long dspStart, long dspNumber) {
00194   unsigned long length;
00195   unsigned long *buffer = dspBlockRead(partition, crate, rod, dspStart, 1, dspNumber, length, true);
00196   if(length != 1) {
00197     cerr << "dspSingleBlockRead failed!\n";
00198   }
00199 
00200   unsigned long val = buffer[0];
00201   delete [] buffer;
00202   return val;
00203 }
00204 
00205 void SctApi::dspSingleBlockWrite(unsigned int partition, unsigned int crate, unsigned int rod,
00206                                  unsigned long dspAddress, unsigned long val, long dspNumber){
00207   unsigned long buffer[1];
00208   buffer[0] = val;
00209   // Use primitive to be on safe side
00210   dspBlockWrite(partition, crate, rod, buffer, dspAddress, 1, dspNumber, true);
00211 }
00212 
00213 
00214 void SctApi::setSlaveBlock(unsigned int partition, unsigned int crate, unsigned int rod, int s, 
00215                            long sAdd, int words, long value, bool usePrim) {
00216   {
00217     boost::mutex::scoped_lock lock(logMutex);
00218     log << "SetSlaveBlock to " << value << endl;
00219   }
00220 
00221   if(usePrim) {
00222     shared_ptr<PrimListWrapper> slList(new PrimListWrapper(1));
00223     PrimBuilder::instance().setMemory(slList, sAdd, words, value);
00224 
00225     shared_ptr<PrimListWrapper> primList(new PrimListWrapper(1));
00226     PrimBuilder::instance().slavePrimList(primList, slList, s, true, false);
00227 
00228     sendPrimList(partition, crate, rod, primList);
00229 
00230     int responseCode = awaitResponse(partition, crate, rod, 10);
00231     if(responseCode == 0) {
00232       cout << "Slave " << s << " block set to " << value << " at address 0x" << hex << sAdd << dec << "\n";
00233     } else {
00234       cout << "Slave set failed\n";
00235     }
00236   } else {
00237     // "Safe" way
00238     unsigned long *buffer = new unsigned long[words];
00239     for(int i=0; i<words; i++) {
00240       buffer[i+5] = value;
00241     }
00242     dspBlockWrite(partition, crate, rod, buffer, sAdd, words, s, usePrim);
00243   }
00244 }
00245 
00246 unsigned long *SctApi::primReadSlaveDsp(unsigned int partition, unsigned int crate, unsigned int rod,
00247                                         int s, int add, int words) {
00248   {
00249     boost::mutex::scoped_lock lock(logMutex);
00250     log << "Read slave (" << s << ") memory 0x" << hex << add << dec << endl;
00251   }
00252 
00253   unsigned long *result = new unsigned long[words];
00254 
00255   /*
00256     Also in buffer:
00257      List header (4) and trailer (2)
00258      Primitive header (4)
00259     (no other primitive data necessary)
00260   */
00261   const int maxLength = (REPLY_BUFF_SIZE)/4 - 6 - 4;
00262 
00263   int wordsDone = 0;
00264   while(wordsDone < words) {
00265     int primLength = min(maxLength, words-wordsDone);
00266 
00267     shared_ptr<PrimListWrapper> rwList(new PrimListWrapper(2));
00268 
00269     PrimBuilder::instance().readSlaveMemory(rwList, s, add+wordsDone*4, primLength);
00270 
00271     sendPrimList(partition, crate, rod, rwList);
00272 
00273     int responseCode = awaitResponse(partition, crate, rod, 10);
00274 
00275     if(responseCode != 0) {
00276       cout << "Read slave memory failed!\n";
00277       return 0;
00278     }
00279 
00280     unsigned long length;
00281     unsigned long *mem = getResponse(partition, crate, rod, length);
00282 
00283     if(!mem) {
00284       return 0;
00285     }
00286 
00287     copy(mem+8, mem+8+primLength, result + wordsDone);
00288     delete [] mem;
00289 
00290     wordsDone += primLength;
00291   }
00292 
00293   return result;
00294 }
00295 
00296 void SctApi::primWriteSlaveDsp(unsigned int partition, unsigned int crate, unsigned int rod,
00297                                int s, int add, int numWords, unsigned long *data) {
00298   {
00299     boost::mutex::scoped_lock lock(logMutex);
00300     log << "Write slave (" << s << ") memory 0x" << hex << add << dec << endl;
00301   }
00302 
00303   /*
00304     Also in buffer:
00305      List header (4) and trailer (2)
00306      Primitive header (4)
00307      Primitive (sizeof(RW_SLAVE_MEMORY_IN)/4)
00308   */
00309   const int maxLength = (PRIM_BUFF_SIZE)/4 - 6 - 4 - sizeof(RW_SLAVE_MEMORY_IN)/4;
00310 
00311   int wordsDone = 0;
00312   while(wordsDone < numWords) {
00313     int primLength = min(maxLength, numWords-wordsDone);
00314 
00315     shared_ptr<PrimListWrapper> rwList(new PrimListWrapper(2));
00316 
00317     long *primData = new long[sizeof(RW_SLAVE_MEMORY_IN)/4 + primLength];
00318 
00319     RW_SLAVE_MEMORY_IN &rwPrim = *(RW_SLAVE_MEMORY_IN*)primData;
00320 
00321 #if (R_RW_SLAVE_MEMORY == 100)
00322     rwPrim.slaveNumber = s;
00323     rwPrim.readNotWrite = 0;
00324     rwPrim.slaveAddress = (UINT32 *)add + wordsDone;
00325     rwPrim.masterAddress = (UINT32 *)0xffffffff;
00326     rwPrim.numWords = primLength;
00327 #else
00328 #error "RW_SLAVE_MEMORY revision change"
00329 #endif
00330 
00331     copy(data + wordsDone, data + wordsDone + primLength, primData + 5);
00332 
00333     rwList->addPrimitive(RodPrimitive(4 + sizeof(RW_SLAVE_MEMORY_IN)/4 + primLength, 
00334                                       1, RW_SLAVE_MEMORY, R_RW_SLAVE_MEMORY, primData),
00335                          primData);
00336 
00337     sendPrimList(partition, crate, rod, rwList);
00338     int responseCode = awaitResponse(partition, crate, rod, 10);
00339 
00340     if(responseCode != 0) {
00341       cout << "Write slave memory failed!\n";
00342       return;
00343     }
00344 
00345     wordsDone += primLength;
00346   }
00347 
00348   return;
00349 }
00350 
00351 shared_array<unsigned long> SctApi::loadFile(string fileName, unsigned long & length) {
00352   shared_array<unsigned long> buffer;
00353   ifstream fin;
00354   fin.open(fileName.c_str(), ios::binary);
00355   if (fin.is_open()) {
00356     unsigned long fileSize;
00357 
00358     // Get size of file
00359     fin.seekg(0, std::ios::end);  // go to end of file
00360     fileSize = fin.tellg();  // file size is current location
00361     fin.seekg(0, std::ios::beg);  // go back to beginning of file
00362 
00363     buffer.reset(new unsigned long[fileSize / 4]);
00364 
00365     fin.read((char *)buffer.get(), fileSize);
00366 
00367     length = fileSize / 4;
00368   }
00369 
00370   return buffer;
00371 }
00372 
00373 // Mainly for starting slaves
00374 void SctApi::writeSlaveFile(unsigned int partition, unsigned int crate, unsigned int rod, unsigned int slave, 
00375                             const string fileName, unsigned long address, bool usePrim) {
00376   cout << "Writing " << fileName << " to slave " << slave << " at 0x" << hex << address << dec << endl;
00377 
00378   unsigned long length;
00379   string nameCopy(fileName);
00380   nameCopy = Sct::Env::substituteVariables(nameCopy);
00381 
00382   shared_array<unsigned long> buffer = loadFile(nameCopy, length);
00383 
00384   if(buffer) {
00385     if(usePrim) {
00386       primWriteSlaveDsp(partition, crate, rod,
00387                         slave, address, length, buffer.get());
00388     } else {
00389       dspBlockWrite(partition, crate, rod,
00390                     buffer.get(), address, length, slave, usePrim);
00391     }
00392   } else {
00393     cout << "Load of file \"" << nameCopy << "\" failed\n";
00394     throw SctApiException("Load of file \"" + nameCopy + "\" failed");
00395   }
00396 
00397   shared_array<unsigned long> readBuffer(primReadSlaveDsp(partition, crate, rod, 
00398                                                           slave, address, length));
00399 
00400   for(unsigned int i=0; i<length; i++) {
00401     if(buffer[i] != readBuffer[i]) {
00402       cout << "Slave write verification failed at " << i << endl;
00403       cout << "\t0x" << hex << buffer[i] << " != 0x" << readBuffer[i] << dec << endl;
00404 
00405       throw SctApiException("Slave verification error: word " + boost::lexical_cast<string>(i));
00406     }
00407   }
00408 }
00409 
00410 } // End namespace

Generated on Thu Feb 3 17:37:42 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5