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