00001
00002
00003
00004 #include "RodModule.h"
00005 #include "BocCard.h"
00006
00008 namespace SctPixelRod {
00009
00010
00011
00012
00013 static long endianSwap = 0;
00014 static const long rodInitTimeout = 10;
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 NoImageFile::NoImageFile(std::string descriptor, std::string fileName) : BaseException(descriptor) {
00028 m_fileName = fileName;
00029 setType(NOIMAGEFILE);
00030 }
00031
00032 void NoImageFile::what(std::ostream& os) {
00033 os << "NoImageFile Exception. Descriptor, File name: " << getDescriptor() << ";" << m_fileName << std::endl;
00034 }
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 HpiException::HpiException( std::string descriptor, unsigned long calcAddr,
00047 unsigned long readAddr) : BaseException(descriptor) {
00048 m_calcAddr = calcAddr;
00049 m_readAddr = readAddr;
00050 setType(HPI);
00051 }
00052
00053 void HpiException::what(std::ostream& os) {
00054 os << "HpiException: " << getDescriptor() << std::endl;
00055 os << "Calculated Address:" << std::hex << getCalcAddr() << std::endl;
00056 os << "Read Address:" << std::hex << getReadAddr() << std::endl;
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 RodException::RodException( std::string descriptor) : BaseException(descriptor) {
00069 m_numData = 0;
00070 m_data1 = m_data2 = 0;
00071 setType(ROD);
00072 }
00073 RodException::RodException( std::string descriptor, unsigned long data1) :
00074 BaseException(descriptor) {
00075 m_numData = 1;
00076 m_data1 = data1;
00077 m_data2 = 0;
00078 setType(ROD);
00079 }
00080 RodException::RodException( std::string descriptor, unsigned long data1,
00081 unsigned long data2) : BaseException(descriptor) {
00082 m_numData = 2;
00083 m_data1 = data1;
00084 m_data2 = data2;
00085 setType(ROD);
00086 }
00087
00088 void RodException::what(std::ostream& os) {
00089 unsigned long numData;
00090 numData = getNumData();
00091 os << "RodException: " << getDescriptor() << std::endl;
00092 if (0 == numData) return;
00093 os << "Data1:" << getData1() << std::endl;
00094 if (1 == numData) return;
00095 os << "Data2:" << getData2() << std::endl;
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 RodModule::RodModule( unsigned long baseAddr, unsigned long mapSize,
00111 VmeInterface & ourInterface, long numSlaves) throw (RodException&,
00112 VmeException&) :
00113 VmeModule(baseAddr, mapSize, ourInterface) {
00114 m_slot = baseAddr>>24;
00115 m_serialNumber = 0xFFFFFFFF;
00116 m_revision = 0;
00117 m_numSlaves = numSlaves;
00118 m_finBufferSize = 4096;
00119 m_masterImageName = std::string("");
00120 m_myOutList = 0;
00121
00122 try {
00123 m_myVmePort = new VmePort(m_baseAddress, m_mapSize, VmeInterface::A32,
00124 m_ourInterface);
00125 }
00126 catch (std::bad_alloc & ba) {
00127 throw RodException("Failed to get VME Port.");
00128 }
00129 for (long i=0; i<4; i++) {
00130 m_slaveIpramName[i]= std::string("");
00131 m_slaveIdramName[i]= std::string("");
00132 m_slaveExtName[i]= std::string("");
00133 }
00134
00135 for(int i=0; i<2; i++) {
00136 m_vmeCommandReg[i] = 0;
00137 }
00138 for(int i=0; i<3; i++) {
00139 m_rodStatusReg[i] = 0;
00140 }
00141
00142 m_myOutList = 0;
00143
00144 for (long i=0; i<N_TXT_BUFFS; i++) {
00145 m_textBuff[i] = 0;
00146 };
00147 m_myTextState = TEXT_IDLE;
00148 m_myPrimState = PRIM_IDLE;
00149 m_textType = TEXT_UNDEF;
00150
00151
00152 getVmePort()->setExceptionTrapping(true);
00153
00154 m_myBoc = new BocCard(*this);
00155 }
00156
00157
00158
00159
00160
00161
00162 RodModule::~RodModule() {
00163 delete(m_myVmePort);
00164 delete m_myBoc;
00165 m_myVmePort = 0;
00166 return;
00167 }
00168
00169
00170
00171
00172
00173
00174 void RodModule::setBoc(BocCard* myBoc) {m_myBoc=myBoc; return;};
00175 BocCard* RodModule::getBocCard() {return m_myBoc; }
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 void RodModule::initialize() {initialize(false); return;};
00193
00194 void RodModule::initialize(bool resetFlag) throw (RodException &, VmeException &) {
00195
00196 unsigned long hpicReadback;
00197 const unsigned long fpgaResetValue = 0x00000020;
00198 const unsigned long rodResetValue = 0x00000040;
00199 unsigned long rodReset, fpgaReset;
00200 unsigned long rodRegValue;
00201 clock_t startTime;
00202
00203
00204 if (resetFlag) {
00205 if (endianSwap) {
00206 rodReset = endianReverse32(rodResetValue);
00207 fpgaReset = endianReverse32(fpgaResetValue);
00208 }
00209 else {
00210 fpgaReset = fpgaResetValue;
00211 rodReset = rodResetValue;
00212 }
00213
00214
00215 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[0], fpgaReset);
00216
00217
00218 rodRegValue = 0;
00219 startTime = time(NULL);
00220 bool change = false;
00221 do {
00222 rodRegValue = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[0]);
00223 if ((time(NULL)-startTime) > DSP_RESET_TIMEOUT) {
00224 throw RodException("FPGA reset timeout in initialize(), DSP_RESET_TIMEOUT=30", rodRegValue);
00225 }
00226
00227 if ((rodRegValue&0x20) == 0x20) change = true;
00228 } while (((rodRegValue&0x3f) != 0x1f) || change==false);
00229
00230
00231 sleep(500);
00232
00233 rodRegValue = readRodStatusReg(0);
00234 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[2], rodReset);
00235
00236
00237 rodRegValue = 0;
00238 startTime = clock();
00239 do {
00240 rodRegValue = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[2]);
00241 if ((clock()-startTime)/CLOCKS_PER_SEC > DSP_RESET_TIMEOUT) {
00242 throw RodException("DSP reset timeout in initialize(), DSP_RESET_TIMEOUT=",
00243 (long)DSP_RESET_TIMEOUT);
00244 }
00245 }
00246 while ((rodRegValue&0x3e) != 0x3e);
00247 rodRegValue = readRodStatusReg(0);
00248
00249
00250 sleep(500);
00251 }
00252
00253
00254 m_serialNumber = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[6]);
00255 if (endianSwap) m_serialNumber = endianReverse32(m_serialNumber);
00256 m_revision = (m_serialNumber&0x00ff0000)>>16;
00257 m_serialNumber = m_serialNumber & 0x3ff;
00258
00259
00260
00261 unsigned long hpicValue = 0x00010001;
00262
00263 hpiLoad(HPIC, hpicValue);
00264 hpicReadback = hpiFetch(HPIC);
00265 sleep(100);
00266
00267
00268 for (long i=0; ; ++i) {
00269 if (readRodStatusBit(0, SR_RUNNING)) {
00270 break;
00271 }
00272 if (i>rodInitTimeout*10) throw RodException("Master DSP init timed out. Tries, Limit:", i,
00273 rodInitTimeout);
00274 sleep(100);
00275 }
00276
00277 for (int i=0; i< N_TXT_BUFFS; i++) {
00278 m_textBuff[i] = (unsigned long *)mdspSingleRead(REPLY_BUFF_BASE + 4*i);
00279 }
00280
00281
00282 m_myTextState = TEXT_IDLE;
00283 m_myPrimState = PRIM_IDLE;
00284
00285 return;
00286 }
00287
00288
00289
00290
00291
00292
00293 void RodModule::reset() throw (RodException&, VmeException &) {
00294
00295 const unsigned long rodResetValue = 0x00000040;
00296 unsigned long rodReset;
00297 unsigned long rodRegValue;
00298 clock_t startTime;
00299
00300 if (endianSwap) {
00301 rodReset = endianReverse32(rodResetValue);
00302 }
00303 else {
00304 rodReset = rodResetValue;
00305 }
00306 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[2], rodReset);
00307 sleep(10000);
00308 rodRegValue = 0;
00309 startTime = clock();
00310 do {
00311 rodRegValue = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[2]);
00312 if ((clock()-startTime)/CLOCKS_PER_SEC > DSP_RESET_TIMEOUT) {
00313 throw RodException("DSP reset timeout in reset() (first call), DSP_RESET_TIMEOUT=",
00314 (long)DSP_RESET_TIMEOUT);
00315 }
00316 }
00317 while (rodRegValue != 0x3e);
00318
00319
00320 unsigned long * buff;
00321 try {
00322
00323 buff = new unsigned long[IDRAM_SZ/sizeof(long)];
00324
00325 for(unsigned int i=0; i<IDRAM_SZ/sizeof(long); i++) {
00326 buff[i] = 0;
00327 }
00328 }
00329 catch (std::bad_alloc & ba) {
00330 throw RodException("Reset() failed to allocate buffer. Size=",
00331 IDRAM_SZ/sizeof(long));
00332 }
00333 mdspBlockWrite(IDRAM_BASE, buff, IDRAM_SZ/sizeof(long));
00334 delete [] buff;
00335
00336
00337 resetMasterDsp();
00338 sleep(50);
00339 for (long i=0; i<m_numSlaves; i++) {
00340 resetSlaveDsp(i);
00341 sleep(50);
00342 rodRegValue = 0;
00343 startTime = clock();
00344 do {
00345 rodRegValue = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[2]);
00346 if ((clock()-startTime)/CLOCKS_PER_SEC > DSP_RESET_TIMEOUT) {
00347 throw RodException("DSP reset timeout in reset() (second call), DSP_RESET_TIMEOUT=",
00348 (long)DSP_RESET_TIMEOUT);
00349 }
00350 }
00351 while (rodRegValue != 0x3e);
00352 };
00353
00354
00355 m_myTextState = TEXT_IDLE;
00356 m_myPrimState = PRIM_IDLE;
00357
00358 return;
00359 }
00360
00361
00362
00363
00364
00365
00366 bool RodModule::verify() throw() {
00367 unsigned long regVal;
00368
00369
00370 regVal = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[6]);
00371 if (endianSwap) regVal = endianReverse32(regVal);
00372 regVal = regVal & 0xff000000;
00373 if (regVal!=0xad000000) return false;
00374 return true;
00375 }
00376
00377
00378
00379 void RodModule::status() throw(){
00380 status(std::cout);
00381 }
00382
00383
00384
00385
00386
00387 void RodModule::status(std::ostream& oss) throw() {
00388 oss << "Slot: " << m_slot;
00389 oss << "Serial Number:" << m_serialNumber;
00390 oss << "Number of slave DSPs: " << m_numSlaves;
00391 oss << std::endl;
00392 std::hex(oss);
00393 oss << "Status registers[0-2]: ";
00394 try {
00395 for (int i=0; i<3; i++) {
00396 oss << readRodStatusReg(i) << " " ;
00397 }
00398 }
00399 catch (VmeException &) {
00400 oss << "status() can't read ROD status registers." << std::flush;
00401 }
00402 oss << std::endl;
00403
00404 oss << "Command registers[0-1]: ";
00405 try {
00406 for (int i=0; i<2; i++) {
00407 oss << readRodCommandReg(i) << " " ;
00408 }
00409 }
00410 catch (VmeException &) {
00411 oss << "status() can't read ROD command registers.\n" << std::flush;
00412 }
00413
00414 std::dec(oss);
00415 oss << "Primitive state: " << getPrimState() << " Text State: " <<
00416 getTextState();
00417 oss << std::endl;
00418 }
00419
00420
00421 void RodModule::initSlaveDsp(const std::string & ipramFile,
00422 const std::string & idramFile,const std::string & extFile,
00423 const long slaveNumber, char opt) throw (RodException&, NoImageFile&, VmeException &) {
00424
00425 unsigned long readBack;
00426 unsigned long hpicValue = 0x00010001;
00427 unsigned long rodRegValue;
00428 clock_t startTime;
00429
00430 if ((slaveNumber < 0) || (slaveNumber >= m_numSlaves)) throw RodException(
00431 "Slave Number out of Range. slaveNumber, m_numSlaves:", slaveNumber,
00432 m_numSlaves);
00433
00434
00435 slvHpiLoad(SLAVE_HPIC_BASE, hpicValue, slaveNumber);
00436 readBack = slvHpiFetch(SLAVE_HPIC_BASE, slaveNumber);
00437
00438
00439 loadSlaveImage(ipramFile, SLAVE_IPRAM_ADDR, slaveNumber, opt);
00440 m_slaveIpramName[slaveNumber] = ipramFile;
00441 loadSlaveImage(idramFile, SLAVE_IDRAM_ADDR, slaveNumber, opt);
00442 m_slaveIdramName[slaveNumber] = idramFile;
00443 loadSlaveImage(extFile, SLAVE_CE2_ADDR, slaveNumber, opt);
00444 m_slaveExtName[slaveNumber] = extFile;
00445
00446
00447 startSlave(slaveNumber);
00448
00449
00450 rodRegValue = 0;
00451 startTime = clock();
00452 do {
00453 rodRegValue = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[2]);
00454 if ((clock()-startTime)/CLOCKS_PER_SEC > DSP_RESET_TIMEOUT) {
00455 throw RodException("DSP reset timeout in initSlaveDsp(), DSP_RESET_TIMEOUT=",
00456 (long)DSP_RESET_TIMEOUT);
00457 }
00458 }
00459 while (rodRegValue != 0x3e);
00460 return;
00461 }
00462
00463
00464
00465
00466 void RodModule::loadSlaveImage(const std::string & fileName, const unsigned long address,
00467 const long slaveNum, char opt) throw (NoImageFile&, RodException&,
00468 VmeException &) {
00469
00470 long numWords;
00471 unsigned long readBack;
00472 int fileSize;
00473 const unsigned long DSP_BUSY_MASK=0x00000002;
00474 std::ifstream fin;
00475
00476 readBack = slvHpiFetch(SLAVE_HPIC_BASE, slaveNum);
00477 if (readBack & DSP_BUSY_MASK) throw RodException(
00478 "loadSlaveImage tried to load to a running SDSP. slavenum = ", slaveNum);
00479
00480 fin.open(fileName.c_str(),std::ios::binary);
00481 if (fin.is_open()) {
00482
00483
00484 fin.seekg(0, std::ios::end);
00485 fileSize = fin.tellg();
00486 fin.seekg(0, std::ios::beg);
00487
00488
00489 char * buffer;
00490 try {
00491 buffer = new char[fileSize];
00492 }
00493 catch (std::bad_alloc & ba) {
00494 throw RodException(
00495 "loadSlaveImage buffer failed to allocate. buffer, fileSize:",
00496 (unsigned long)buffer, (unsigned long)fileSize);
00497 }
00498 fin.read(buffer, fileSize);
00499
00500
00501 numWords = (fileSize+3)/4;
00502 slvBlockWrite(address, (unsigned long*) buffer, numWords, slaveNum);
00503
00504
00505 if (opt=='v') {
00506 char* buffer2;
00507 try {
00508 buffer2 = new char[fileSize];
00509 }
00510 catch (std::bad_alloc & ba) {
00511 throw RodException(
00512 "loadSlaveImage buffer2 failed to allocate. buffer, fileSize:",
00513 (unsigned long)buffer, (unsigned long)fileSize);
00514 }
00515 slvBlockRead(address, (unsigned long*)buffer2, numWords, slaveNum);
00516
00517 for (int i=0; i<fileSize; i++) {
00518 if (buffer[i] != buffer2[i]) {
00519 delete [] buffer;
00520 delete [] buffer2;
00521 fin.close();
00522 char message[] = "loadSlaveImage buffer readback invalid for file, slavenum, char index: ";
00523 throw RodException( message+fileName, slaveNum, i);
00524 }
00525 }
00526 delete [] buffer2;
00527 std::cout << "Image verification check complete\n";
00528 }
00529
00530
00531 fin.close();
00532 delete [] buffer;
00533 }
00534 else {
00535 throw NoImageFile("NoImageFile thrown from loadSlaveImage", fileName);
00536 }
00537 return;
00538 }
00539
00540
00541
00542
00543
00544
00545
00546 void RodModule::startSlave(const long slaveNumber, char mode)
00547 throw(RodException&, VmeException &) {
00548 const unsigned long dspint = 0x2;
00549
00550 if (mode == 'q') {
00551 slvHpiLoad(SLAVE_HPIC_BASE, dspint, slaveNumber);
00552 }
00553
00554 else {
00555 long primData[4]={slaveNumber, 1, 2, 0x200000};
00556 RodPrimitive * startSlaveExec;
00557 try {
00558 startSlaveExec = new RodPrimitive(8, 1, START_SLAVE_EXECUTING,
00559 R_START_SLAVE_EXECUTING, primData);
00560 }
00561 catch (std::bad_alloc & ba) {
00562 throw RodException(
00563 "startSlave unable to allocate startSlaveExec. slaveNumber:", slaveNumber);
00564 }
00565 synchSendPrim(*startSlaveExec);
00566 delete startSlaveExec;
00567 }
00568
00569 return;
00570 }
00571
00572
00573
00574
00575 void RodModule::synchSendPrim(RodPrimitive & prim) throw (RodException&,
00576 VmeException &) {
00577 RodPrimList primList(1);
00578 long myTextLength;
00579 TEXT_BUFFER_TYPE myTextType;
00580 PrimState returnPState;
00581 TextBuffState returnTState;
00582
00583
00584 char * myTextBuffer;
00585 try {
00586 myTextBuffer = new char[TEXT_BUFF_SIZE];
00587 }
00588 catch (std::bad_alloc & ba) {
00589 throw RodException(
00590 "synchSendPrim failed to allocate text. Size=", TEXT_BUFF_SIZE);
00591 }
00592 primList.insert(primList.begin(), prim);
00593 try {
00594 primList.bufferBuild();
00595 }
00596 catch (PrimListException &p) {
00597
00598 std::cout << p.getDescriptor() << " ";
00599 std::cout << p.getData1() << ", " << p.getData2() << "\n";
00600 };
00601 try {
00602 this->sendPrimList(&primList);
00603 }
00604 catch (BaseException &h) {
00605 std::cout << h;
00606 };
00607
00608
00609
00610
00611
00612 do {
00613 returnPState = this->primHandler();
00614 returnTState = this->textHandler();
00615
00616
00617 while (returnTState == TEXT_RQ_SET) {
00618 do {
00619 returnTState = this->textHandler();
00620 } while (returnTState != TEXT_READOUT);
00621 this->getTextBuffer(myTextBuffer, myTextLength, myTextType);
00622 this->clearTextBuffer();
00623 for (int i=0; i<myTextLength; i++) {
00624 std::cout << myTextBuffer[i];
00625 if (0==(i+1)%64) std::cout << std::endl;
00626 }
00627 std::cout << std::endl;
00628 returnTState = this->textHandler();
00629 }
00630 } while (returnPState != PRIM_EXECUTING);
00631 do {
00632 try {
00633 returnPState = this->primHandler();
00634 }
00635 catch (RodException &r) {
00636 std::cout << r.getDescriptor() <<", " << r.getData1() << ", " << r.getData2()
00637 << '\n';
00638 }
00639 } while (returnPState != PRIM_WAITING && returnPState != PRIM_IDLE);
00640 delete [] myTextBuffer;
00641
00642 return;
00643 }
00644
00645
00646
00647 void RodModule::sendPrimList(RodPrimList *l) throw(PrimListException &, VmeException &) {
00648
00649 unsigned long * buffAddr;
00650 long buffCount;
00651
00652 if (!l->getBuffer()) {
00653 l->bufferBuild();
00654 };
00655
00656 buffCount = l->getBufferLength();
00657
00658 if(abs(buffCount) > PRIM_BUFF_SIZE) {
00659 throw PrimListException("PrimList is bigger than DSP buffer", buffCount, PRIM_BUFF_SIZE);
00660 }
00661
00662 buffAddr = l->getBuffer();
00663 mdspBlockWrite(PRIM_BUFF_BASE, buffAddr, buffCount);
00664 m_myPrimState = PRIM_LOADED;
00665
00666 return;
00667 }
00668
00669
00670
00671 PrimState RodModule::primHandler() throw(RodException &, VmeException &) {
00672 long wordCount;
00673 unsigned long status;
00674 unsigned long* buffptr;
00675 unsigned long replyBuffer;
00676 switch (m_myPrimState) {
00677 case PRIM_LOADED: {
00678 if (0==getDspAck()) {
00679 setInListReady();
00680 m_myPrimState = PRIM_EXECUTING;
00681 };
00682 break;
00683 };
00684 case PRIM_EXECUTING: {
00685 status = readRodStatusReg(0);
00686 if (1==getDspAck()) {
00687 if (status >> TEXT_BUFF_NOT_EMPTY[0]) {
00688
00689 }
00690 if (1==readRodStatusBit(0,OUTLIST_READY)) {
00691
00692 hpiLoad(HPIA, REPLY_BUFF_BASE);
00693 wordCount = hpiFetch(HPID_NOAUTO);
00694
00695
00696
00697
00698
00699
00700
00701 RodOutList* outList;
00702 try {
00703 outList = new RodOutList(wordCount);
00704 }
00705 catch (std::bad_alloc & ba) {
00706 throw RodException("Outlist creation failed. WordCount=",
00707 wordCount);
00708 }
00709 if (0==outList->getBody()) throw RodException(
00710 "Outlist failed to allocate body array.WordCount=", wordCount);
00711
00712
00713 this->setOutList(outList);
00714
00715
00716 buffptr = m_myOutList->getBody();
00717 replyBuffer = REPLY_BUFF_BASE;
00718 mdspBlockRead(replyBuffer, buffptr, wordCount);
00719 m_myPrimState = PRIM_WAITING;
00720 }
00721 else m_myPrimState = PRIM_IDLE;
00722 clearVmeCommandRegBit(INLISTRDY);
00723 }
00724 break;
00725 };
00726 default: {
00727 break;
00728 };
00729 };
00730 return m_myPrimState;
00731 };
00732
00733
00734
00735 void RodModule::deleteOutList() throw() {
00736 delete m_myOutList;
00737 m_myOutList = 0;
00738 return;
00739 };
00740
00741
00742
00743 TextBuffState RodModule::textHandler() throw(VmeException &) {
00744 unsigned long regValue;
00745 unsigned long dataPtr;
00746 long txtLength, txtLength1, txtLength2, txtWords;
00747 switch (m_myTextState) {
00748 case TEXT_IDLE: {
00749 regValue = readRodStatusReg(0) & SR_TEXT_MASK;
00750 if (0==regValue) return m_myTextState;
00751 for (long i=0; i<4; i++) {
00752 if (regValue & SR_TEXT_BIT_MASK[i]) {
00753 m_textType = (TEXT_BUFFER_TYPE)i;
00754 setVmeCommandRegBit(TEXT_BUFF_READ_REQ[m_textType]);
00755 sleep(10);
00756 m_myTextState = TEXT_RQ_SET;
00757 return m_myTextState;
00758 };
00759 }
00760 break;
00761 };
00762 case TEXT_RQ_SET: {
00763 if (readRodStatusReg(0) & SR_TEXT_BIT_MASK[m_textType]) {
00764 return m_myTextState;
00765 };
00766 hpiLoad( HPIA, (unsigned long)m_textBuff[m_textType]);
00767 m_txtBuffer.dataEnd = hpiFetch(HPID_AUTO);
00768 m_txtBuffer.readIndx = hpiFetch(HPID_AUTO);
00769 m_txtBuffer.writeIndx = hpiFetch(HPID_AUTO);
00770 m_txtBuffer.mode = hpiFetch(HPID_AUTO);
00771 m_txtBuffer.overwrite = hpiFetch(HPID_AUTO);
00772 m_txtBuffer.overflow = hpiFetch(HPID_AUTO);
00773 m_txtBuffer.wrap = hpiFetch(HPID_AUTO);
00774 m_txtBuffer.state = hpiFetch(HPID_AUTO);
00775 m_txtBuffer.id = hpiFetch(HPID_AUTO);
00776 m_txtBuffer.data = (char *)hpiFetch(HPID_AUTO);
00777 dataPtr = (unsigned long)m_txtBuffer.data;
00778
00779
00780 if (m_txtBuffer.readIndx < m_txtBuffer.writeIndx) {
00781 txtLength = m_txtBuffer.writeIndx - m_txtBuffer.readIndx;
00782 txtWords = (txtLength+3)/4;
00783 mdspBlockRead(dataPtr, (unsigned long*)m_textData, txtWords);
00784 }
00785 else {
00786 txtLength1 = TEXT_BUFF_SIZE - m_txtBuffer.readIndx;
00787 txtWords = (txtLength1+3)/4;
00788 mdspBlockRead(dataPtr+4*m_txtBuffer.readIndx, (unsigned long*)m_textData, txtWords);
00789 txtLength2 = m_txtBuffer.writeIndx;
00790 txtWords = (txtLength2+3)/4;
00791 mdspBlockRead(dataPtr, (unsigned long*)(m_textData+4*txtLength1), txtWords);
00792 txtLength = txtLength1 + txtLength2;
00793 };
00794 clearVmeCommandRegBit(TEXT_BUFF_READ_REQ[m_textType]);
00795 sleep(10);
00796 m_myTextState = TEXT_READOUT;
00797 m_txtBuffer.state = txtLength;
00798 return m_myTextState;
00799 break;
00800 };
00801 default: {
00802 return m_myTextState;
00803 break;
00804 };
00805 };
00806
00807 return m_myTextState;
00808 };
00809
00810
00811
00812
00813 void RodModule::getTextBuffer(char * buffer, long & length,
00814 TEXT_BUFFER_TYPE & type) throw() {
00815 length = m_txtBuffer.state;
00816 type = (TEXT_BUFFER_TYPE)m_textType;
00817 for (int i=0; i<m_txtBuffer.state; i++) {
00818 buffer[i] = m_textData[i];
00819 };
00820 return;
00821 };
00822
00823
00824
00825 void RodModule::clearTextBuffer() throw() {
00826 m_textType = TEXT_UNDEF;
00827 m_txtBuffer.state = 0;
00828 m_myTextState = TEXT_IDLE;
00829 return;
00830 };
00831
00832
00833
00834 void RodModule::hpiLoad(unsigned long hpiReg, unsigned long hpiValue)
00835 throw(VmeException &) {
00836
00837 if (endianSwap) hpiValue = endianReverse32(hpiValue);
00838 m_myVmePort->write32(hpiReg, hpiValue);
00839 };
00840
00841
00842
00843 unsigned long RodModule::hpiFetch(unsigned long hpiReg)
00844 throw(VmeException &){
00845
00846 unsigned long hpiValue;
00847
00848 hpiValue=m_myVmePort->read32(hpiReg);
00849 if (endianSwap) hpiValue = endianReverse32(hpiValue);
00850
00851 return hpiValue;
00852 };
00853
00854
00855
00856 unsigned long RodModule::mdspSingleRead(const unsigned long dspAddr)
00857 throw(VmeException &) {
00858 unsigned long value;
00859
00860
00861 hpiLoad(HPIA, dspAddr);
00862
00863
00864 value = m_myVmePort->read32(HPID_NOAUTO);
00865 if (endianSwap) {
00866 value = endianReverse32(value);
00867 }
00868 return value;
00869 };
00870
00871
00872
00873 void RodModule::mdspSingleWrite(unsigned long dspAddr, unsigned long buffer)
00874 throw(VmeException &) {
00875
00876
00877 hpiLoad(HPIA, dspAddr);
00878
00879
00880 if (endianSwap) {
00881 buffer = endianReverse32(buffer);
00882 }
00883
00884 m_myVmePort->write32(HPID_NOAUTO, buffer);
00885
00886 return;
00887 };
00888
00889
00890
00891
00892 void RodModule::mdspBlockRead(const unsigned long dspAddr, unsigned long buffer[],
00893 const long wordCount, HpidMode mode) throw (HpiException &,
00894 VmeException &) {
00895 unsigned long hpidAddr;
00896 long myCount, localCount, blockWordCount, wordIncr;
00897
00898
00899 switch (mode) {
00900 case AUTO:
00901 hpidAddr= HPID_AUTO;
00902 break;
00903 case NO_AUTO:
00904 hpidAddr = HPID_NOAUTO;
00905 break;
00906 case DYNAMIC:
00907 default:
00908 if (wordCount == 1){
00909 hpidAddr = HPID_NOAUTO;
00910 }
00911 else {
00912 hpidAddr = HPID_AUTO;
00913 };
00914 break;
00915 };
00916
00917
00918 hpiLoad(HPIA, dspAddr);
00919
00920
00921
00922 localCount = wordCount;
00923 wordIncr = 0;
00924 if (wordCount%2 !=0) {
00925 buffer[0] = m_myVmePort->read32(hpidAddr);
00926 wordIncr = 1;
00927 localCount -= 1;
00928 }
00929
00930
00931
00932
00933 blockWordCount = std::min(localCount, MAX_HPID_WORD_ELEMENTS);
00934
00935
00936 for (myCount=localCount; myCount>0;
00937 myCount-=blockWordCount, wordIncr+=blockWordCount) {
00938
00939
00940 blockWordCount = std::min(myCount, MAX_HPID_WORD_ELEMENTS);
00941
00942
00943
00944
00945 m_myVmePort->blockRead32(hpidAddr, buffer+wordIncr, blockWordCount*4);
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958 }
00959 return;
00960 };
00961
00962
00963
00964 void RodModule::mdspBlockWrite(unsigned long dspAddr, unsigned long buffer[],
00965 long wordCount, HpidMode mode) throw (HpiException &,
00966 VmeException &) {
00967
00968 unsigned long hpidAddr;
00969 long myCount, localCount, blockWordCount, wordIncr;
00970
00971
00972 hpiLoad(HPIA, dspAddr);
00973
00974
00975 switch (mode) {
00976 case AUTO:
00977 hpidAddr= HPID_AUTO;
00978 break;
00979 case NO_AUTO:
00980 hpidAddr = HPID_NOAUTO;
00981 break;
00982 case DYNAMIC:
00983 default:
00984 if (wordCount == 1){
00985 hpidAddr = HPID_NOAUTO;
00986 }
00987 else {
00988 hpidAddr = HPID_AUTO;
00989 };
00990 break;
00991 };
00992
00993
00994
00995 localCount = wordCount;
00996 wordIncr = 0;
00997 if (wordCount%2 !=0) {
00998 m_myVmePort->write32(hpidAddr, buffer[0]);
00999 wordIncr = 1;
01000 localCount -= 1;
01001 }
01002
01003
01004
01005
01006 blockWordCount = std::min(wordCount, MAX_HPID_WORD_ELEMENTS);
01007
01008
01009 for (myCount=localCount; myCount>0;
01010 myCount-=blockWordCount, wordIncr+=blockWordCount) {
01011
01012
01013 blockWordCount = std::min(myCount, MAX_HPID_WORD_ELEMENTS);
01014
01015
01016 if (endianSwap) {
01017 for (int i=0; i<blockWordCount; i++) {
01018 buffer[wordIncr+i] = endianReverse32(buffer[wordIncr+i]);
01019 }
01020 }
01021
01022
01023
01024 m_myVmePort->blockWrite32(hpidAddr, &buffer[wordIncr], blockWordCount*4);
01025
01026
01027
01028
01029
01030
01031
01032 }
01033 return;
01034 };
01035
01036
01037
01038 void RodModule::mdspBlockDump(const unsigned long firstAddress,
01039 const unsigned long lastAddress,
01040 const std::string & fileName) throw(RodException &, VmeException &) {
01041
01042 long numBytes;
01043 std::ofstream fout;
01044 numBytes = lastAddress - firstAddress + 1;
01045 fout.open(fileName.c_str(), std::ios::binary);
01046 if (fout.is_open()) {
01047 unsigned long * buffer;
01048 try {
01049 buffer = new unsigned long[numBytes];
01050 }
01051 catch (std::bad_alloc & ba) {
01052 throw RodException(
01053 "mdspBlockDump failed to allocate buffer; buffer size in bytes=", numBytes);
01054 }
01055 mdspBlockRead(firstAddress, buffer, numBytes/4);
01056 fout.write((char*)buffer, numBytes);
01057 fout.close();
01058 delete [] buffer;
01059 }
01060 else {
01061 throw RodException("mdspBlockDump failed to open file");
01062 }
01063 return;
01064 }
01065
01066
01067
01068 void RodModule::slvHpiLoad(unsigned long hpiReg, unsigned long hpiValue,
01069 long slaveNum) throw(VmeException &) {
01070
01071 unsigned long address;
01072 address = hpiReg + slaveNum*SLAVE_HPI_OFFSET;
01073
01074 mdspSingleWrite(address, hpiValue);
01075 };
01076
01077
01078
01079 unsigned long RodModule::slvHpiFetch(unsigned long hpiReg, long slaveNum)
01080 throw(VmeException &) {
01081
01082 unsigned long hpiValue;
01083 unsigned long address;
01084 address = hpiReg + slaveNum*SLAVE_HPI_OFFSET;
01085
01086 hpiValue=mdspSingleRead(address);
01087
01088 return hpiValue;
01089 };
01090
01091
01092 unsigned long RodModule::slvSingleRead(unsigned long dspAddr, long slaveNum )
01093 throw(VmeException &) {
01094
01095 unsigned long slvHpia, slvHpid;
01096 unsigned long value;
01097 slvHpia = SLAVE_HPIA_BASE + slaveNum*SLAVE_HPI_OFFSET;
01098 slvHpid = SLAVE_HPID_NOAUTO_BASE + slaveNum*SLAVE_HPI_OFFSET;
01099
01100
01101 mdspSingleWrite(slvHpia, dspAddr);
01102
01103
01104 value = mdspSingleRead(slvHpid);
01105
01106 return value;
01107 };
01108
01109
01110
01111 void RodModule::slvSingleWrite(unsigned long dspAddr, unsigned long buffer,
01112 long slaveNum) throw(VmeException &) {
01113
01114 unsigned long slvHpia, slvHpid;
01115 slvHpia = SLAVE_HPIA_BASE + slaveNum*SLAVE_HPI_OFFSET;
01116 slvHpid = SLAVE_HPID_NOAUTO_BASE + slaveNum*SLAVE_HPI_OFFSET;
01117
01118 mdspSingleWrite(slvHpia, dspAddr);
01119
01120
01121 mdspSingleWrite(slvHpid, buffer);
01122
01123 return;
01124 };
01125
01126
01127
01128 void RodModule::slvBlockRead(const unsigned long dspAddr, unsigned long buffer[],
01129 const long wordCount, long slaveNum, HpidMode mode)
01130 throw (HpiException &, VmeException &) {
01131
01132 unsigned long hpidAddr, dspAddrLocal, hpiaAfterFetch, hpiaAfterCalc;
01133 long myCount, blockWordCount, wordIncr;
01134 unsigned long slvHpia, slvHpidAuto, slvHpidNoAuto;
01135 slvHpia = SLAVE_HPIA_BASE + slaveNum*SLAVE_HPI_OFFSET;
01136 slvHpidAuto = SLAVE_HPID_AUTO_BASE + slaveNum*SLAVE_HPI_OFFSET;
01137 slvHpidNoAuto = SLAVE_HPID_NOAUTO_BASE + slaveNum*SLAVE_HPI_OFFSET;
01138
01139
01140
01141 switch (mode) {
01142 case AUTO:
01143 hpidAddr= slvHpidAuto;
01144 break;
01145 case NO_AUTO:
01146 hpidAddr = slvHpidNoAuto;
01147 break;
01148 case DYNAMIC:
01149 default:
01150 if (wordCount == 1){
01151 hpidAddr = slvHpidNoAuto;
01152 }
01153 else {
01154 hpidAddr = slvHpidAuto;
01155 };
01156 break;
01157 };
01158
01159
01160 mdspSingleWrite(slvHpia, dspAddr);
01161
01162
01163
01164
01165 blockWordCount = std::min(wordCount, MAX_HPID_WORD_ELEMENTS);
01166
01167
01168 for (myCount=wordCount, wordIncr=0; myCount>0;
01169 myCount-=blockWordCount, wordIncr+=blockWordCount) {
01170
01171
01172 blockWordCount = std::min(myCount, MAX_HPID_WORD_ELEMENTS);
01173
01174
01175 dspAddrLocal = dspAddr+ (4*wordIncr);
01176 mdspBlockRead(hpidAddr, &buffer[wordIncr], blockWordCount, NO_AUTO);
01177 }
01178
01179
01180 hpiaAfterFetch = mdspSingleRead(slvHpia);
01181 if (wordCount == 1) {
01182 hpiaAfterCalc = dspAddr;
01183 } else {
01184 hpiaAfterCalc = dspAddr+wordCount*4;
01185 }
01186
01187
01188
01189
01190
01191 return;
01192 };
01193
01194
01195
01196 void RodModule::slvBlockWrite(unsigned long dspAddr, unsigned long buffer[],
01197 long wordCount, long slaveNum, HpidMode mode)
01198 throw (HpiException &, VmeException &) {
01199
01200 unsigned long hpidAddr, dspAddrLocal, hpiaAfterFetch, hpiaAfterCalc;
01201 long myCount, blockWordCount, wordIncr;
01202 unsigned long slvHpia, slvHpidAuto, slvHpidNoAuto;
01203 slvHpia = SLAVE_HPIA_BASE + slaveNum*SLAVE_HPI_OFFSET;
01204 slvHpidAuto = SLAVE_HPID_AUTO_BASE + slaveNum*SLAVE_HPI_OFFSET;
01205 slvHpidNoAuto = SLAVE_HPID_NOAUTO_BASE + slaveNum*SLAVE_HPI_OFFSET;
01206
01207
01208 mdspSingleWrite(slvHpia, dspAddr);
01209
01210
01211 switch (mode) {
01212 case AUTO:
01213 hpidAddr= slvHpidAuto;
01214 break;
01215 case NO_AUTO:
01216 hpidAddr = slvHpidNoAuto;
01217 break;
01218 case DYNAMIC:
01219 default:
01220 if (wordCount == 1){
01221 hpidAddr = slvHpidNoAuto;
01222 }
01223 else {
01224 hpidAddr = slvHpidAuto;
01225 };
01226 break;
01227 };
01228
01229
01230
01231
01232 blockWordCount = std::min(wordCount, MAX_HPID_WORD_ELEMENTS);
01233
01234
01235 for (myCount=wordCount, wordIncr=0; myCount>0;
01236 myCount-=blockWordCount, wordIncr+=blockWordCount) {
01237
01238
01239 blockWordCount = std::min(myCount, MAX_HPID_WORD_ELEMENTS);
01240
01241
01242 dspAddrLocal = dspAddr+ (4*wordIncr);
01243 mdspBlockWrite(hpidAddr, &buffer[wordIncr], blockWordCount, NO_AUTO);
01244 }
01245
01246
01247 hpiaAfterFetch = mdspSingleRead(slvHpia);
01248
01249 if (wordCount == 1) {
01250 hpiaAfterCalc = dspAddr;
01251 }
01252 else {
01253 hpiaAfterCalc = dspAddr+wordCount*4-4;
01254 }
01255
01256
01257
01258
01259
01260
01261 return;
01262 };
01263
01264
01265
01266 void RodModule::resetMasterDsp() throw(RodException&, VmeException &) {
01267 unsigned long value=0;
01268 unsigned long rodRegValue;
01269 clock_t startTime;
01270
01271 rodRegValue = readRodStatusReg(0);
01272 setBit(&value, 1);
01273 if (endianSwap) {
01274 value = endianReverse32(value);
01275 }
01276 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[2], value);
01277 sleep(4000);
01278 rodRegValue = 0;
01279 startTime = clock();
01280 do {
01281 rodRegValue = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[2]);
01282 if ((clock()-startTime)/CLOCKS_PER_SEC > DSP_RESET_TIMEOUT) {
01283 throw RodException("DSP reset timeout in resetMasterDsp(), DSP_RESET_TIMEOUT=",
01284 (long)DSP_RESET_TIMEOUT);
01285 }
01286 }
01287 while (rodRegValue != 0x3e);
01288 rodRegValue = readRodStatusReg(0);
01289
01290 return;
01291 };
01292
01293
01294
01295 void RodModule::resetSlaveDsp(long slaveNumber) throw(RodException&, VmeException &) {
01296 unsigned long value=0;
01297 unsigned long rodRegValue;
01298 clock_t startTime;
01299
01300 setBit(&value, 2+slaveNumber);
01301 if (endianSwap) {
01302 value = endianReverse32(value);
01303 }
01304 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[2], value);
01305 sleep(4000);
01306 rodRegValue = 0;
01307 startTime = clock();
01308 do {
01309 rodRegValue = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[2]);
01310 if ((clock()-startTime)/CLOCKS_PER_SEC > DSP_RESET_TIMEOUT) {
01311 throw RodException("DSP reset timeout in resetSlaveDsp(), DSP_RESET_TIMEOUT=",
01312 (long)DSP_RESET_TIMEOUT);
01313 }
01314 }
01315 while (rodRegValue != 0x3e);
01316
01317 return;
01318 };
01319
01320
01321
01322
01323 void RodModule::resetAllDsps() throw(RodException &, VmeException &) {
01324 unsigned long value=0;
01325 unsigned long rodRegValue;
01326 clock_t startTime;
01327
01328 setBit(&value, 6);
01329 if (endianSwap) {
01330 value = endianReverse32(value);
01331 }
01332 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[2], value);
01333 sleep(4000);
01334 rodRegValue = 0;
01335 startTime = clock();
01336 do {
01337 rodRegValue = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[2]);
01338 if ((clock()-startTime)/CLOCKS_PER_SEC > DSP_RESET_TIMEOUT) {
01339 throw RodException("DSP reset timeout in resetAllDsps(), DSP_RESET_TIMEOUT=",
01340 (long)DSP_RESET_TIMEOUT);
01341 }
01342 }
01343 while (rodRegValue != 0x3e);
01344
01345 return;
01346 };
01347
01348
01349
01350 void RodModule::chipEraseHpi() throw(VmeException &) {
01351 unsigned long value = 0x10;
01352
01353
01354 commonEraseCommandsHpi(MDSP_FLASH_BOTTOM);
01355
01356
01357 mdspSingleWrite(MDSP_FLASH_BOTTOM+(0x5555<<2), value);
01358
01359
01360 sleep(CHIP_ERASE_TIME_MS);
01361 return;
01362 };
01363
01364
01365
01366 void RodModule::sectorErase(unsigned long sectorBaseAddress)
01367 throw(RodException &, VmeException &) {
01368 unsigned long flashBaseAddress, valueD32;
01369 bool busyBit;
01370
01371
01372 switch (m_revision) {
01373 case 0x0f:
01374 case 0x0e:
01375 flashBaseAddress = FPGA_FLASH_REL_ADDR_REVE;
01376 break;
01377 case 0x0b:
01378 case 0x0c:
01379 default:
01380 if ((sectorBaseAddress<FPGA_FLASH_0_BOTTOM)||
01381 (sectorBaseAddress>FPGA_FLASH_2_BOTTOM+FLASH_MEMORY_SIZE)) {
01382 throw RodException("Flash sector base addr out of range, sectorBaseAddress=",
01383 sectorBaseAddress);
01384 }
01385 if (sectorBaseAddress<FPGA_FLASH_1_BOTTOM) {
01386 flashBaseAddress = FPGA_FLASH_0_BOTTOM;
01387 }
01388 else if (sectorBaseAddress<FPGA_FLASH_2_BOTTOM) {
01389 flashBaseAddress = FPGA_FLASH_1_BOTTOM;
01390 }
01391 else flashBaseAddress = FPGA_FLASH_2_BOTTOM;
01392 break;
01393 }
01394
01395 commonEraseCommands(flashBaseAddress);
01396
01397
01398 vmeWriteElementFlash(0x30, sectorBaseAddress, WRITE_COMMAND_HANDSHAKE_BIT);
01399
01400
01401 switch (m_revision ) {
01402 case 0x0f:
01403 case 0x0e:
01404 do {
01405 valueD32 = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[4]);
01406 busyBit = readBit(valueD32, 3);
01407 } while (busyBit);
01408 break;
01409 case 0x0b:
01410 case 0x0c:
01411 default:
01412 sleep(SECTOR_ERASE_TIME_MS);
01413 break;
01414 }
01415
01416 return;
01417 };
01418
01419
01420
01421 void RodModule::writeByteToFlash(unsigned long address, UINT8 data)
01422 throw (RodException &, VmeException &) {
01423 UINT8 readData;
01424 clock_t startTime;
01425 long updateAddress;
01426
01427 if (data!=0xFF) {
01428
01429 vmeWriteElementFlash(data, address, WRITE_DATA_HANDSHAKE_BIT);
01430 updateAddress = 0;
01431 }
01432 else {
01433 updateAddress = 1;
01434 }
01435
01436
01437 startTime = clock();
01438 while(1) {
01439 readData = readByteFromFlash(address, updateAddress);
01440 if (readData == data) return;
01441 else if((clock()-startTime)/CLOCKS_PER_SEC > FLASH_TIMEOUT) {
01442 throw RodException("Flash timeout in writeByteToFlash, FLASH_TIMEOUT=",
01443 (long)FLASH_TIMEOUT);
01444 }
01445 }
01446 return;
01447 };
01448
01449
01450
01451 void RodModule::writeBlockToFlash(unsigned long address, UINT8 *data,
01452 unsigned long numBytes) throw(RodException &, VmeException &) {
01453 unsigned long index, sectorSize;
01454 switch (m_revision) {
01455 case 0x0f:
01456 case 0x0e:
01457 sectorSize = FLASH_SECTOR_SIZE_REVE;
01458 break;
01459 case 0x0b:
01460 case 0x0c:
01461 default:
01462 sectorSize = FLASH_SECTOR_SIZE;
01463 break;
01464 }
01465 for (index=0; index<numBytes; ++index) {
01466 if ((index%sectorSize)==0) {
01467 sectorErase(address+index);
01468 }
01469 writeByteToFlash(address+index, *(data+index));
01470 }
01471 return;
01472 };
01473
01474
01475
01476 void RodModule::writeBlockToFlashHpi(unsigned long address, UINT8 *data,
01477 unsigned long numBytes) throw (RodException &, VmeException &) {
01478 unsigned long index, sectorAddr;
01479 const unsigned long eraseData=0x30;
01480 const unsigned long data1=0xAA;
01481 const unsigned long data2=0x55;
01482 const unsigned long data3=0xA0;
01483 const unsigned long addr1=MDSP_FLASH_BOTTOM+(0x5555<<2);
01484 const unsigned long addr2=MDSP_FLASH_BOTTOM+(0x2AAA<<2);
01485 unsigned long byteRelAddr;
01486 long words;
01487 UINT8 dataVal, verifyVal;
01488 unsigned long longVal, busyVal;
01489
01490 for (index=0; index<numBytes; ++index) {
01491 byteRelAddr = address+index-MDSP_FLASH_BOTTOM;
01492 if ((index%FLASH_SECTOR_SIZE)==0) {
01493
01494
01495 commonEraseCommandsHpi(MDSP_FLASH_BOTTOM);
01496
01497 sectorAddr = MDSP_FLASH_BOTTOM+
01498 (byteRelAddr<<2);
01499 mdspSingleWrite(sectorAddr, eraseData);
01500
01501 sleep(SECTOR_ERASE_TIME_MS);
01502 };
01503
01504
01505 dataVal = *(data+index);
01506 longVal = dataVal&0x000000FF;
01507 if (dataVal != 0xFF) {
01508 mdspSingleWrite(addr1, data1);
01509 mdspSingleWrite(addr2, data2);
01510 mdspSingleWrite(addr1, data3);
01511 mdspSingleWrite(MDSP_FLASH_BOTTOM+(byteRelAddr<<2), longVal);
01512
01513
01514 for (int i=0; i<4000; i++) {
01515 busyVal = mdspSingleRead(MDSP_FLASH_BOTTOM+byteRelAddr);
01516 switch (byteRelAddr%4) {
01517 case 1: busyVal = busyVal >> 8;
01518 break;
01519 case 2: busyVal = busyVal >> 16;
01520 break;
01521 case 3: busyVal = busyVal >> 24;
01522 break;
01523 default: break;
01524 }
01525 busyVal = busyVal & 0x000000FF;
01526 if (busyVal == longVal) break;
01527 }
01528 };
01529 };
01530
01531
01532 words = (numBytes+3)/4;
01533 UINT8 *buffer;
01534 try {
01535 buffer = new UINT8[words*4];
01536 }
01537 catch (std::bad_alloc & ba) {
01538 throw RodException("writeBlockToFlashHpi unable to get buffer.");
01539 }
01540 mdspBlockRead(address, (unsigned long*)buffer, words);
01541 for (index=0; index<numBytes; ++index) {
01542 dataVal = *(data+index);
01543 verifyVal = *(buffer+index);
01544 if (dataVal != verifyVal) {
01545 delete [] buffer;
01546 throw RodException("writeBlockToFlashHpi verify failed. index, data:", index,
01547 dataVal);
01548 };
01549 }
01550 delete [] buffer;
01551 return;
01552 };
01553
01554
01555
01556 UINT8 RodModule::readByteFromFlash(unsigned long address, long updateAddress)
01557 throw (RodException &, VmeException &){
01558 UINT8 dataByte;
01559 unsigned long commandReg;
01560 clock_t startTime;
01561 unsigned long handshakeBitValue = 0;
01562 unsigned long valueD32;
01563
01564 if (updateAddress) {
01565 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[4], address);
01566 }
01567
01568 setBit(&handshakeBitValue, READ_HANDSHAKE_BIT);
01569 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[3], handshakeBitValue);
01570
01571
01572 startTime = clock();
01573 while (1) {
01574 commandReg = m_myVmePort->read32(FPGA_CONTROL_REG_REL_ADDR[3]);
01575 if (0==readBit(commandReg, READ_HANDSHAKE_BIT)) break;
01576 if ((clock()-startTime)>FLASH_TIMEOUT) throw RodException(
01577 "Timeout in readByteFromFlash. Address=", address);
01578 }
01579
01580
01581 valueD32 = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[7]);
01582 dataByte = (UINT8)(valueD32&0xFF);
01583 return dataByte;
01584 };
01585
01586
01587
01588 void RodModule::vmeWriteElementFlash(UINT8 value, unsigned long address,
01589 long handshakeBit) throw (RodException &, VmeException &) {
01590 unsigned long ctrlReg4Val;
01591 unsigned long commandReg;
01592 clock_t startTime;
01593 unsigned long handshakeBitValue=0;
01594
01595 ctrlReg4Val = (value<<24)| address;
01596 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[4], ctrlReg4Val);
01597
01598
01599 setBit(&handshakeBitValue, handshakeBit);
01600 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[3], handshakeBitValue);
01601
01602
01603 startTime = clock();
01604 while(1) {
01605 commandReg = m_myVmePort->read32(FPGA_CONTROL_REG_REL_ADDR[3]);
01606 if (0==readBit(commandReg, handshakeBit)) break;
01607 if ((clock()-startTime)>FLASH_TIMEOUT) throw RodException(
01608 "Timeout in vmeWriteElementFlash. Address, value=",
01609 address, (unsigned long)value);
01610 }
01611 return;
01612 };
01613
01614
01615
01616 void RodModule::readBlockFromFlash(unsigned long address, UINT8 *buffer,
01617 unsigned long numBytes) throw(RodException &, VmeException &) {
01618 unsigned long index;
01619 for (index=0; index<numBytes; ++index) {
01620 buffer[index] = readByteFromFlash(address+index, 1);
01621 }
01622 return;
01623 };
01624
01625
01626
01627 void RodModule::commonEraseCommands(unsigned long flashBaseAddr)
01628 throw(RodException &, VmeException &) {
01629
01630 const unsigned long addr1 = flashBaseAddr+0x5555;
01631 const unsigned long addr2 = flashBaseAddr+0x2AAA;
01632
01633
01634 vmeWriteElementFlash(0xAA, addr1, WRITE_COMMAND_HANDSHAKE_BIT);
01635
01636
01637 vmeWriteElementFlash(0x55, addr2, WRITE_COMMAND_HANDSHAKE_BIT);
01638
01639
01640 vmeWriteElementFlash(0x80, addr1, WRITE_COMMAND_HANDSHAKE_BIT);
01641
01642
01643 vmeWriteElementFlash(0xAA, addr1, WRITE_COMMAND_HANDSHAKE_BIT);
01644
01645
01646 vmeWriteElementFlash(0x55, addr2, WRITE_COMMAND_HANDSHAKE_BIT);
01647
01648 return;
01649 };
01650
01651
01652
01653 void RodModule::commonEraseCommandsHpi(unsigned long flashBaseAddr)
01654 throw(VmeException &) {
01655
01656 unsigned long buffer;
01657 const unsigned long addr1 = flashBaseAddr+(0x5555<<2);
01658 const unsigned long addr2 = flashBaseAddr+(0x2AAA<<2);
01659
01660
01661 buffer = 0xAA;
01662 mdspSingleWrite(addr1, buffer);
01663
01664
01665 buffer = 0x55;
01666 mdspSingleWrite(addr2, buffer);
01667
01668
01669 buffer = 0x80;
01670 mdspSingleWrite(addr1, buffer);
01671
01672
01673 buffer = 0xAA;
01674 mdspSingleWrite(addr1, buffer);
01675
01676
01677 buffer = 0x55;
01678 mdspSingleWrite(addr2, buffer);
01679
01680 return;
01681 };
01682
01683
01684
01685 unsigned long RodModule::getFlashSectorSize() {
01686 unsigned long sectorSize;
01687 switch (m_revision) {
01688 case 0x0f:
01689 case 0x0e:
01690 sectorSize = FLASH_SECTOR_SIZE_REVE;
01691 break;
01692 case 0x0b:
01693 case 0x0c:
01694 default:
01695 sectorSize = FLASH_SECTOR_SIZE;
01696 break;
01697 }
01698 return sectorSize;
01699 };
01700
01701
01702
01703 void RodModule::sleep(const double milliSecs) {
01704 clock_t start, delay;
01705 delay = CLOCKS_PER_SEC;
01706 delay = clock_t(milliSecs * CLOCKS_PER_SEC / 1000 );
01707
01708 start = clock();
01709 while (clock()-start< delay)
01710 ;
01711 return;
01712 };
01713
01714
01715
01716 unsigned long RodModule::checkSum(const unsigned long *sourceArray, const long wordCount) {
01717 unsigned long result=0;
01718 long i;
01719
01720 for (i=0; i<wordCount; ++i) {
01721 result ^= sourceArray[i];
01722 }
01723 return result;
01724 };
01725
01726
01727
01728 unsigned long RodModule::endianReverse32(const unsigned long inVal) {
01729 unsigned long outVal;
01730 outVal = (inVal & 0x000000ff) << 24;
01731 outVal |= (inVal & 0x0000ff00) << 8;
01732 outVal |= (inVal & 0x00ff0000) >> 8;
01733 outVal |= (inVal & 0xff000000) >> 24;
01734 return outVal;
01735 };
01736
01737 }
01738
01739
01740
01741
01742 std::ostream& operator<<(std::ostream& os, SctPixelRod::RodModule& rod) {
01743 os << "Slot: " << rod.getSlot() << std::endl;
01744 os << "Serial Number:" << rod.getSerialNumber() << std::endl;
01745 os << "Number of slave DSPs: " << rod.getNumSlaves() << std::endl;
01746 os << "Status registers[0-2]: ";
01747 try {
01748 for (int i=0; i<3; i++) {
01749 os << std::hex << rod.readRodStatusReg(i) << " ";
01750 }
01751 os << std::endl;
01752 }
01753 catch (SctPixelRod::VmeException &) {
01754 os << "VmeException while reading ROD status registers. " << std::endl;
01755 }
01756
01757 os << "Command registers[0-1]: ";
01758 try {
01759 for (int i=0; i<2; i++) {
01760 os << std::hex << rod.readRodCommandReg(i) << " ";
01761 }
01762 os << std::endl;
01763 }
01764 catch (SctPixelRod::VmeException &) {
01765 os << "VmeException while reading ROD command registers. " << std::endl;
01766 }
01767
01768 os << "Primitive state: " << rod.getPrimState() << " Text State: " <<
01769 rod.getTextState() << std::dec << std::endl;
01770 return os;
01771 }
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792