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
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
00041
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
00052 unsigned long length;
00053 unsigned long *buffer = dspBlockRead(rod, dspStart, numWords, dspNumber, length, usePrim);
00054
00055 if(!buffer) {
00056
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
00077
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
00098 delete [] buffer;
00099 } else {
00100 cout << "Block read failed!\n";
00101 return 1;
00102 }
00103
00104 return 0;
00105 }
00106
00107
00108
00109
00110
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
00132 unsigned long * buffer = new unsigned long[numWords];
00133
00134 for(int i=0; i<numWords; i++) {
00135 buffer[i] = 0;
00136 }
00137
00138
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
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
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
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
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
00270
00271
00272
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
00323
00324
00325
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
00382 fin.seekg(0, std::ios::end);
00383 fileSize = fin.tellg();
00384 fin.seekg(0, std::ios::beg);
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
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 }