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

Generated on Mon Feb 6 14:01:28 2006 for SCT DAQ/DCS Software - C++ by  doxygen 1.4.6