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

Generated on Fri Sep 16 18:01:57 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5