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
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
00038
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
00049 unsigned long length;
00050 unsigned long *buffer = dspBlockRead(partition, crate, rod, dspStart, numWords, dspNumber, length, usePrim);
00051
00052 if(!buffer) {
00053
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
00074
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
00095 delete [] buffer;
00096 } else {
00097 cout << "Block read failed!\n";
00098 return 1;
00099 }
00100
00101 return 0;
00102 }
00103
00104
00105
00106
00107
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
00129 unsigned long * buffer = new unsigned long[numWords];
00130
00131 for(int i=0; i<numWords; i++) {
00132 buffer[i] = 0;
00133 }
00134
00135
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
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
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
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
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
00257
00258
00259
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
00305
00306
00307
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
00359 fin.seekg(0, std::ios::end);
00360 fileSize = fin.tellg();
00361 fin.seekg(0, std::ios::beg);
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
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 }