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
00380
00381
00382 void RodModule::status() throw() {
00383 std::cout << "Slot: " << m_slot;
00384 std::cout << "Serial Number:" << m_serialNumber;
00385 std::cout << "Number of slave DSPs: " << m_numSlaves;
00386 std::cout << std::endl;
00387 std::hex(std::cout);
00388 std::cout << "Status registers[0-2]: ";
00389 try {
00390 for (int i=0; i<3; i++) {
00391 std::cout << readRodStatusReg(i) << " " ;
00392 }
00393 }
00394 catch (VmeException &) {
00395 std::cout << "status() can't read ROD status registers." << std::flush;
00396 }
00397 std::cout << std::endl;
00398
00399 std::cout << "Command registers[0-1]: ";
00400 try {
00401 for (int i=0; i<2; i++) {
00402 std::cout << readRodCommandReg(i) << " " ;
00403 }
00404 }
00405 catch (VmeException &) {
00406 std::cout << "status() can't read ROD command registers.\n" << std::flush;
00407 }
00408
00409 std::dec(std::cout);
00410 std::cout << "Primitive state: " << getPrimState() << " Text State: " <<
00411 getTextState();
00412 std::cout << std::endl;
00413 return;
00414 }
00415
00416
00417 void RodModule::initSlaveDsp(const std::string & ipramFile,
00418 const std::string & idramFile,const std::string & extFile,
00419 const long slaveNumber, char opt) throw (RodException&, NoImageFile&, VmeException &) {
00420
00421 unsigned long readBack;
00422 unsigned long hpicValue = 0x00010001;
00423 unsigned long rodRegValue;
00424 clock_t startTime;
00425
00426 if ((slaveNumber < 0) || (slaveNumber >= m_numSlaves)) throw RodException(
00427 "Slave Number out of Range. slaveNumber, m_numSlaves:", slaveNumber,
00428 m_numSlaves);
00429
00430
00431 slvHpiLoad(SLAVE_HPIC_BASE, hpicValue, slaveNumber);
00432 readBack = slvHpiFetch(SLAVE_HPIC_BASE, slaveNumber);
00433
00434
00435 loadSlaveImage(ipramFile, SLAVE_IPRAM_ADDR, slaveNumber, opt);
00436 m_slaveIpramName[slaveNumber] = ipramFile;
00437 loadSlaveImage(idramFile, SLAVE_IDRAM_ADDR, slaveNumber, opt);
00438 m_slaveIdramName[slaveNumber] = idramFile;
00439 loadSlaveImage(extFile, SLAVE_CE2_ADDR, slaveNumber, opt);
00440 m_slaveExtName[slaveNumber] = extFile;
00441
00442
00443 startSlave(slaveNumber);
00444
00445
00446 rodRegValue = 0;
00447 startTime = clock();
00448 do {
00449 rodRegValue = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[2]);
00450 if ((clock()-startTime)/CLOCKS_PER_SEC > DSP_RESET_TIMEOUT) {
00451 throw RodException("DSP reset timeout in initSlaveDsp(), DSP_RESET_TIMEOUT=",
00452 (long)DSP_RESET_TIMEOUT);
00453 }
00454 }
00455 while (rodRegValue != 0x3e);
00456 return;
00457 }
00458
00459
00460
00461
00462 void RodModule::loadSlaveImage(const std::string & fileName, const unsigned long address,
00463 const long slaveNum, char opt) throw (NoImageFile&, RodException&,
00464 VmeException &) {
00465
00466 long numWords;
00467 unsigned long readBack;
00468 int fileSize;
00469 const unsigned long DSP_BUSY_MASK=0x00000002;
00470 std::ifstream fin;
00471
00472 readBack = slvHpiFetch(SLAVE_HPIC_BASE, slaveNum);
00473 if (readBack & DSP_BUSY_MASK) throw RodException(
00474 "loadSlaveImage tried to load to a running SDSP. slavenum = ", slaveNum);
00475
00476 fin.open(fileName.c_str(),std::ios::binary);
00477 if (fin.is_open()) {
00478
00479
00480 fin.seekg(0, std::ios::end);
00481 fileSize = fin.tellg();
00482 fin.seekg(0, std::ios::beg);
00483
00484
00485 char * buffer;
00486 try {
00487 buffer = new char[fileSize];
00488 }
00489 catch (std::bad_alloc & ba) {
00490 throw RodException(
00491 "loadSlaveImage buffer failed to allocate. buffer, fileSize:",
00492 (unsigned long)buffer, (unsigned long)fileSize);
00493 }
00494 fin.read(buffer, fileSize);
00495
00496
00497 numWords = (fileSize+3)/4;
00498 slvBlockWrite(address, (unsigned long*) buffer, numWords, slaveNum);
00499
00500
00501 if (opt=='v') {
00502 char* buffer2;
00503 try {
00504 buffer2 = new char[fileSize];
00505 }
00506 catch (std::bad_alloc & ba) {
00507 throw RodException(
00508 "loadSlaveImage buffer2 failed to allocate. buffer, fileSize:",
00509 (unsigned long)buffer, (unsigned long)fileSize);
00510 }
00511 slvBlockRead(address, (unsigned long*)buffer2, numWords, slaveNum);
00512
00513 for (int i=0; i<fileSize; i++) {
00514 if (buffer[i] != buffer2[i]) {
00515 delete [] buffer;
00516 delete [] buffer2;
00517 fin.close();
00518 char message[] = "loadSlaveImage buffer readback invalid for file, slavenum, char index: ";
00519 throw RodException( message+fileName, slaveNum, i);
00520 }
00521 }
00522 delete [] buffer2;
00523 std::cout << "Image verification check complete\n";
00524 }
00525
00526
00527 fin.close();
00528 delete [] buffer;
00529 }
00530 else {
00531 throw NoImageFile("NoImageFile thrown from loadSlaveImage", fileName);
00532 }
00533 return;
00534 }
00535
00536
00537
00538
00539
00540
00541
00542 void RodModule::startSlave(const long slaveNumber, char mode)
00543 throw(RodException&, VmeException &) {
00544 const unsigned long dspint = 0x2;
00545
00546 if (mode == 'q') {
00547 slvHpiLoad(SLAVE_HPIC_BASE, dspint, slaveNumber);
00548 }
00549
00550 else {
00551 long primData[4]={slaveNumber, 1, 2, 0x200000};
00552 RodPrimitive * startSlaveExec;
00553 try {
00554 startSlaveExec = new RodPrimitive(8, 1, START_SLAVE_EXECUTING,
00555 R_START_SLAVE_EXECUTING, primData);
00556 }
00557 catch (std::bad_alloc & ba) {
00558 throw RodException(
00559 "startSlave unable to allocate startSlaveExec. slaveNumber:", slaveNumber);
00560 }
00561 synchSendPrim(*startSlaveExec);
00562 delete startSlaveExec;
00563 }
00564
00565 return;
00566 }
00567
00568
00569
00570
00571 void RodModule::synchSendPrim(RodPrimitive & prim) throw (RodException&,
00572 VmeException &) {
00573 RodPrimList primList(1);
00574 long myTextLength;
00575 TEXT_BUFFER_TYPE myTextType;
00576 PrimState returnPState;
00577 TextBuffState returnTState;
00578
00579
00580 char * myTextBuffer;
00581 try {
00582 myTextBuffer = new char[TEXT_BUFF_SIZE];
00583 }
00584 catch (std::bad_alloc & ba) {
00585 throw RodException(
00586 "synchSendPrim failed to allocate text. Size=", TEXT_BUFF_SIZE);
00587 }
00588 primList.insert(primList.begin(), prim);
00589 try {
00590 primList.bufferBuild();
00591 }
00592 catch (PrimListException &p) {
00593
00594 std::cout << p.getDescriptor() << " ";
00595 std::cout << p.getData1() << ", " << p.getData2() << "\n";
00596 };
00597 try {
00598 this->sendPrimList(&primList);
00599 }
00600 catch (BaseException &h) {
00601 std::cout << h;
00602 };
00603
00604
00605
00606
00607
00608 do {
00609 returnPState = this->primHandler();
00610 returnTState = this->textHandler();
00611
00612
00613 while (returnTState == TEXT_RQ_SET) {
00614 do {
00615 returnTState = this->textHandler();
00616 } while (returnTState != TEXT_READOUT);
00617 this->getTextBuffer(myTextBuffer, myTextLength, myTextType);
00618 this->clearTextBuffer();
00619 for (int i=0; i<myTextLength; i++) {
00620 std::cout << myTextBuffer[i];
00621 if (0==(i+1)%64) std::cout << std::endl;
00622 }
00623 std::cout << std::endl;
00624 returnTState = this->textHandler();
00625 }
00626 } while (returnPState != PRIM_EXECUTING);
00627 do {
00628 try {
00629 returnPState = this->primHandler();
00630 }
00631 catch (RodException &r) {
00632 std::cout << r.getDescriptor() <<", " << r.getData1() << ", " << r.getData2()
00633 << '\n';
00634 }
00635 } while (returnPState != PRIM_WAITING && returnPState != PRIM_IDLE);
00636 delete [] myTextBuffer;
00637
00638 return;
00639 }
00640
00641
00642
00643 void RodModule::sendPrimList(RodPrimList *l) throw(PrimListException &, VmeException &) {
00644
00645 unsigned long * buffAddr;
00646 long buffCount;
00647
00648 if (!l->getBuffer()) {
00649 l->bufferBuild();
00650 };
00651
00652 buffCount = l->getBufferLength();
00653
00654 if(abs(buffCount) > PRIM_BUFF_SIZE) {
00655 throw PrimListException("PrimList is bigger than DSP buffer", buffCount, PRIM_BUFF_SIZE);
00656 }
00657
00658 buffAddr = l->getBuffer();
00659 mdspBlockWrite(PRIM_BUFF_BASE, buffAddr, buffCount);
00660 m_myPrimState = PRIM_LOADED;
00661
00662 return;
00663 }
00664
00665
00666
00667 PrimState RodModule::primHandler() throw(RodException &, VmeException &) {
00668 long wordCount;
00669 unsigned long status;
00670 unsigned long* buffptr;
00671 unsigned long replyBuffer;
00672 switch (m_myPrimState) {
00673 case PRIM_LOADED: {
00674 if (0==getDspAck()) {
00675 setInListReady();
00676 m_myPrimState = PRIM_EXECUTING;
00677 };
00678 break;
00679 };
00680 case PRIM_EXECUTING: {
00681 status = readRodStatusReg(0);
00682 if (1==getDspAck()) {
00683 if (status >> TEXT_BUFF_NOT_EMPTY[0]) {
00684
00685 }
00686 if (1==readRodStatusBit(0,OUTLIST_READY)) {
00687
00688 hpiLoad(HPIA, REPLY_BUFF_BASE);
00689 wordCount = hpiFetch(HPID_NOAUTO);
00690
00691
00692
00693
00694
00695
00696
00697 RodOutList* outList;
00698 try {
00699 outList = new RodOutList(wordCount);
00700 }
00701 catch (std::bad_alloc & ba) {
00702 throw RodException("Outlist creation failed. WordCount=",
00703 wordCount);
00704 }
00705 if (0==outList->getBody()) throw RodException(
00706 "Outlist failed to allocate body array.WordCount=", wordCount);
00707
00708
00709 this->setOutList(outList);
00710
00711
00712 buffptr = m_myOutList->getBody();
00713 replyBuffer = REPLY_BUFF_BASE;
00714 mdspBlockRead(replyBuffer, buffptr, wordCount);
00715 m_myPrimState = PRIM_WAITING;
00716 }
00717 else m_myPrimState = PRIM_IDLE;
00718 clearVmeCommandRegBit(INLISTRDY);
00719 }
00720 break;
00721 };
00722 default: {
00723 break;
00724 };
00725 };
00726 return m_myPrimState;
00727 };
00728
00729
00730
00731 void RodModule::deleteOutList() throw() {
00732 delete m_myOutList;
00733 m_myOutList = 0;
00734 return;
00735 };
00736
00737
00738
00739 TextBuffState RodModule::textHandler() throw(VmeException &) {
00740 unsigned long regValue;
00741 unsigned long dataPtr;
00742 long txtLength, txtLength1, txtLength2, txtWords;
00743 switch (m_myTextState) {
00744 case TEXT_IDLE: {
00745 regValue = readRodStatusReg(0) & SR_TEXT_MASK;
00746 if (0==regValue) return m_myTextState;
00747 for (long i=0; i<4; i++) {
00748 if (regValue & SR_TEXT_BIT_MASK[i]) {
00749 m_textType = (TEXT_BUFFER_TYPE)i;
00750 setVmeCommandRegBit(TEXT_BUFF_READ_REQ[m_textType]);
00751 sleep(10);
00752 m_myTextState = TEXT_RQ_SET;
00753 return m_myTextState;
00754 };
00755 }
00756 break;
00757 };
00758 case TEXT_RQ_SET: {
00759 if (readRodStatusReg(0) & SR_TEXT_BIT_MASK[m_textType]) {
00760 return m_myTextState;
00761 };
00762 hpiLoad( HPIA, (unsigned long)m_textBuff[m_textType]);
00763 m_txtBuffer.dataEnd = hpiFetch(HPID_AUTO);
00764 m_txtBuffer.readIndx = hpiFetch(HPID_AUTO);
00765 m_txtBuffer.writeIndx = hpiFetch(HPID_AUTO);
00766 m_txtBuffer.mode = hpiFetch(HPID_AUTO);
00767 m_txtBuffer.overwrite = hpiFetch(HPID_AUTO);
00768 m_txtBuffer.overflow = hpiFetch(HPID_AUTO);
00769 m_txtBuffer.wrap = hpiFetch(HPID_AUTO);
00770 m_txtBuffer.state = hpiFetch(HPID_AUTO);
00771 m_txtBuffer.id = hpiFetch(HPID_AUTO);
00772 m_txtBuffer.data = (char *)hpiFetch(HPID_AUTO);
00773 dataPtr = (unsigned long)m_txtBuffer.data;
00774
00775
00776 if (m_txtBuffer.readIndx < m_txtBuffer.writeIndx) {
00777 txtLength = m_txtBuffer.writeIndx - m_txtBuffer.readIndx;
00778 txtWords = (txtLength+3)/4;
00779 mdspBlockRead(dataPtr, (unsigned long*)m_textData, txtWords);
00780 }
00781 else {
00782 txtLength1 = TEXT_BUFF_SIZE - m_txtBuffer.readIndx;
00783 txtWords = (txtLength1+3)/4;
00784 mdspBlockRead(dataPtr+4*m_txtBuffer.readIndx, (unsigned long*)m_textData, txtWords);
00785 txtLength2 = m_txtBuffer.writeIndx;
00786 txtWords = (txtLength2+3)/4;
00787 mdspBlockRead(dataPtr, (unsigned long*)(m_textData+4*txtLength1), txtWords);
00788 txtLength = txtLength1 + txtLength2;
00789 };
00790 clearVmeCommandRegBit(TEXT_BUFF_READ_REQ[m_textType]);
00791 sleep(10);
00792 m_myTextState = TEXT_READOUT;
00793 m_txtBuffer.state = txtLength;
00794 return m_myTextState;
00795 break;
00796 };
00797 default: {
00798 return m_myTextState;
00799 break;
00800 };
00801 };
00802
00803 return m_myTextState;
00804 };
00805
00806
00807
00808
00809 void RodModule::getTextBuffer(char * buffer, long & length,
00810 TEXT_BUFFER_TYPE & type) throw() {
00811 length = m_txtBuffer.state;
00812 type = (TEXT_BUFFER_TYPE)m_textType;
00813 for (int i=0; i<m_txtBuffer.state; i++) {
00814 buffer[i] = m_textData[i];
00815 };
00816 return;
00817 };
00818
00819
00820
00821 void RodModule::clearTextBuffer() throw() {
00822 m_textType = TEXT_UNDEF;
00823 m_txtBuffer.state = 0;
00824 m_myTextState = TEXT_IDLE;
00825 return;
00826 };
00827
00828
00829
00830 void RodModule::hpiLoad(unsigned long hpiReg, unsigned long hpiValue)
00831 throw(VmeException &) {
00832
00833 if (endianSwap) hpiValue = endianReverse32(hpiValue);
00834 m_myVmePort->write32(hpiReg, hpiValue);
00835 };
00836
00837
00838
00839 unsigned long RodModule::hpiFetch(unsigned long hpiReg)
00840 throw(VmeException &){
00841
00842 unsigned long hpiValue;
00843
00844 hpiValue=m_myVmePort->read32(hpiReg);
00845 if (endianSwap) hpiValue = endianReverse32(hpiValue);
00846
00847 return hpiValue;
00848 };
00849
00850
00851
00852 unsigned long RodModule::mdspSingleRead(const unsigned long dspAddr)
00853 throw(VmeException &) {
00854 unsigned long value;
00855
00856
00857 hpiLoad(HPIA, dspAddr);
00858
00859
00860 value = m_myVmePort->read32(HPID_NOAUTO);
00861 if (endianSwap) {
00862 value = endianReverse32(value);
00863 }
00864 return value;
00865 };
00866
00867
00868
00869 void RodModule::mdspSingleWrite(unsigned long dspAddr, unsigned long buffer)
00870 throw(VmeException &) {
00871
00872
00873 hpiLoad(HPIA, dspAddr);
00874
00875
00876 if (endianSwap) {
00877 buffer = endianReverse32(buffer);
00878 }
00879
00880 m_myVmePort->write32(HPID_NOAUTO, buffer);
00881
00882 return;
00883 };
00884
00885
00886
00887
00888 void RodModule::mdspBlockRead(const unsigned long dspAddr, unsigned long buffer[],
00889 const long wordCount, HpidMode mode) throw (HpiException &,
00890 VmeException &) {
00891 unsigned long hpidAddr;
00892 long myCount, localCount, blockWordCount, wordIncr;
00893
00894
00895 switch (mode) {
00896 case AUTO:
00897 hpidAddr= HPID_AUTO;
00898 break;
00899 case NO_AUTO:
00900 hpidAddr = HPID_NOAUTO;
00901 break;
00902 case DYNAMIC:
00903 default:
00904 if (wordCount == 1){
00905 hpidAddr = HPID_NOAUTO;
00906 }
00907 else {
00908 hpidAddr = HPID_AUTO;
00909 };
00910 break;
00911 };
00912
00913
00914 hpiLoad(HPIA, dspAddr);
00915
00916
00917
00918 localCount = wordCount;
00919 wordIncr = 0;
00920 if (wordCount%2 !=0) {
00921 buffer[0] = m_myVmePort->read32(hpidAddr);
00922 wordIncr = 1;
00923 localCount -= 1;
00924 }
00925
00926
00927
00928
00929 blockWordCount = std::min(localCount, MAX_HPID_WORD_ELEMENTS);
00930
00931
00932 for (myCount=localCount; myCount>0;
00933 myCount-=blockWordCount, wordIncr+=blockWordCount) {
00934
00935
00936 blockWordCount = std::min(myCount, MAX_HPID_WORD_ELEMENTS);
00937
00938
00939
00940
00941 m_myVmePort->blockRead32(hpidAddr, buffer+wordIncr, blockWordCount*4);
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954 }
00955 return;
00956 };
00957
00958
00959
00960 void RodModule::mdspBlockWrite(unsigned long dspAddr, unsigned long buffer[],
00961 long wordCount, HpidMode mode) throw (HpiException &,
00962 VmeException &) {
00963
00964 unsigned long hpidAddr;
00965 long myCount, localCount, blockWordCount, wordIncr;
00966
00967
00968 hpiLoad(HPIA, dspAddr);
00969
00970
00971 switch (mode) {
00972 case AUTO:
00973 hpidAddr= HPID_AUTO;
00974 break;
00975 case NO_AUTO:
00976 hpidAddr = HPID_NOAUTO;
00977 break;
00978 case DYNAMIC:
00979 default:
00980 if (wordCount == 1){
00981 hpidAddr = HPID_NOAUTO;
00982 }
00983 else {
00984 hpidAddr = HPID_AUTO;
00985 };
00986 break;
00987 };
00988
00989
00990
00991 localCount = wordCount;
00992 wordIncr = 0;
00993 if (wordCount%2 !=0) {
00994 m_myVmePort->write32(hpidAddr, buffer[0]);
00995 wordIncr = 1;
00996 localCount -= 1;
00997 }
00998
00999
01000
01001
01002 blockWordCount = std::min(wordCount, MAX_HPID_WORD_ELEMENTS);
01003
01004
01005 for (myCount=localCount; myCount>0;
01006 myCount-=blockWordCount, wordIncr+=blockWordCount) {
01007
01008
01009 blockWordCount = std::min(myCount, MAX_HPID_WORD_ELEMENTS);
01010
01011
01012 if (endianSwap) {
01013 for (int i=0; i<blockWordCount; i++) {
01014 buffer[wordIncr+i] = endianReverse32(buffer[wordIncr+i]);
01015 }
01016 }
01017
01018
01019
01020 m_myVmePort->blockWrite32(hpidAddr, &buffer[wordIncr], blockWordCount*4);
01021
01022
01023
01024
01025
01026
01027
01028 }
01029 return;
01030 };
01031
01032
01033
01034 void RodModule::mdspBlockDump(const unsigned long firstAddress,
01035 const unsigned long lastAddress,
01036 const std::string & fileName) throw(RodException &, VmeException &) {
01037
01038 long numBytes;
01039 std::ofstream fout;
01040 numBytes = lastAddress - firstAddress + 1;
01041 fout.open(fileName.c_str(), std::ios::binary);
01042 if (fout.is_open()) {
01043 unsigned long * buffer;
01044 try {
01045 buffer = new unsigned long[numBytes];
01046 }
01047 catch (std::bad_alloc & ba) {
01048 throw RodException(
01049 "mdspBlockDump failed to allocate buffer; buffer size in bytes=", numBytes);
01050 }
01051 mdspBlockRead(firstAddress, buffer, numBytes/4);
01052 fout.write((char*)buffer, numBytes);
01053 fout.close();
01054 delete [] buffer;
01055 }
01056 else {
01057 throw RodException("mdspBlockDump failed to open file");
01058 }
01059 return;
01060 }
01061
01062
01063
01064 void RodModule::slvHpiLoad(unsigned long hpiReg, unsigned long hpiValue,
01065 long slaveNum) throw(VmeException &) {
01066
01067 unsigned long address;
01068 address = hpiReg + slaveNum*SLAVE_HPI_OFFSET;
01069
01070 mdspSingleWrite(address, hpiValue);
01071 };
01072
01073
01074
01075 unsigned long RodModule::slvHpiFetch(unsigned long hpiReg, long slaveNum)
01076 throw(VmeException &) {
01077
01078 unsigned long hpiValue;
01079 unsigned long address;
01080 address = hpiReg + slaveNum*SLAVE_HPI_OFFSET;
01081
01082 hpiValue=mdspSingleRead(address);
01083
01084 return hpiValue;
01085 };
01086
01087
01088 unsigned long RodModule::slvSingleRead(unsigned long dspAddr, long slaveNum )
01089 throw(VmeException &) {
01090
01091 unsigned long slvHpia, slvHpid;
01092 unsigned long value;
01093 slvHpia = SLAVE_HPIA_BASE + slaveNum*SLAVE_HPI_OFFSET;
01094 slvHpid = SLAVE_HPID_NOAUTO_BASE + slaveNum*SLAVE_HPI_OFFSET;
01095
01096
01097 mdspSingleWrite(slvHpia, dspAddr);
01098
01099
01100 value = mdspSingleRead(slvHpid);
01101
01102 return value;
01103 };
01104
01105
01106
01107 void RodModule::slvSingleWrite(unsigned long dspAddr, unsigned long buffer,
01108 long slaveNum) throw(VmeException &) {
01109
01110 unsigned long slvHpia, slvHpid;
01111 slvHpia = SLAVE_HPIA_BASE + slaveNum*SLAVE_HPI_OFFSET;
01112 slvHpid = SLAVE_HPID_NOAUTO_BASE + slaveNum*SLAVE_HPI_OFFSET;
01113
01114 mdspSingleWrite(slvHpia, dspAddr);
01115
01116
01117 mdspSingleWrite(slvHpid, buffer);
01118
01119 return;
01120 };
01121
01122
01123
01124 void RodModule::slvBlockRead(const unsigned long dspAddr, unsigned long buffer[],
01125 const long wordCount, long slaveNum, HpidMode mode)
01126 throw (HpiException &, VmeException &) {
01127
01128 unsigned long hpidAddr, dspAddrLocal, hpiaAfterFetch, hpiaAfterCalc;
01129 long myCount, blockWordCount, wordIncr;
01130 unsigned long slvHpia, slvHpidAuto, slvHpidNoAuto;
01131 slvHpia = SLAVE_HPIA_BASE + slaveNum*SLAVE_HPI_OFFSET;
01132 slvHpidAuto = SLAVE_HPID_AUTO_BASE + slaveNum*SLAVE_HPI_OFFSET;
01133 slvHpidNoAuto = SLAVE_HPID_NOAUTO_BASE + slaveNum*SLAVE_HPI_OFFSET;
01134
01135
01136
01137 switch (mode) {
01138 case AUTO:
01139 hpidAddr= slvHpidAuto;
01140 break;
01141 case NO_AUTO:
01142 hpidAddr = slvHpidNoAuto;
01143 break;
01144 case DYNAMIC:
01145 default:
01146 if (wordCount == 1){
01147 hpidAddr = slvHpidNoAuto;
01148 }
01149 else {
01150 hpidAddr = slvHpidAuto;
01151 };
01152 break;
01153 };
01154
01155
01156 mdspSingleWrite(slvHpia, dspAddr);
01157
01158
01159
01160
01161 blockWordCount = std::min(wordCount, MAX_HPID_WORD_ELEMENTS);
01162
01163
01164 for (myCount=wordCount, wordIncr=0; myCount>0;
01165 myCount-=blockWordCount, wordIncr+=blockWordCount) {
01166
01167
01168 blockWordCount = std::min(myCount, MAX_HPID_WORD_ELEMENTS);
01169
01170
01171 dspAddrLocal = dspAddr+ (4*wordIncr);
01172 mdspBlockRead(hpidAddr, &buffer[wordIncr], blockWordCount, NO_AUTO);
01173 }
01174
01175
01176 hpiaAfterFetch = mdspSingleRead(slvHpia);
01177 if (wordCount == 1) {
01178 hpiaAfterCalc = dspAddr;
01179 } else {
01180 hpiaAfterCalc = dspAddr+wordCount*4;
01181 }
01182
01183
01184
01185
01186
01187 return;
01188 };
01189
01190
01191
01192 void RodModule::slvBlockWrite(unsigned long dspAddr, unsigned long buffer[],
01193 long wordCount, long slaveNum, HpidMode mode)
01194 throw (HpiException &, VmeException &) {
01195
01196 unsigned long hpidAddr, dspAddrLocal, hpiaAfterFetch, hpiaAfterCalc;
01197 long myCount, blockWordCount, wordIncr;
01198 unsigned long slvHpia, slvHpidAuto, slvHpidNoAuto;
01199 slvHpia = SLAVE_HPIA_BASE + slaveNum*SLAVE_HPI_OFFSET;
01200 slvHpidAuto = SLAVE_HPID_AUTO_BASE + slaveNum*SLAVE_HPI_OFFSET;
01201 slvHpidNoAuto = SLAVE_HPID_NOAUTO_BASE + slaveNum*SLAVE_HPI_OFFSET;
01202
01203
01204 mdspSingleWrite(slvHpia, dspAddr);
01205
01206
01207 switch (mode) {
01208 case AUTO:
01209 hpidAddr= slvHpidAuto;
01210 break;
01211 case NO_AUTO:
01212 hpidAddr = slvHpidNoAuto;
01213 break;
01214 case DYNAMIC:
01215 default:
01216 if (wordCount == 1){
01217 hpidAddr = slvHpidNoAuto;
01218 }
01219 else {
01220 hpidAddr = slvHpidAuto;
01221 };
01222 break;
01223 };
01224
01225
01226
01227
01228 blockWordCount = std::min(wordCount, MAX_HPID_WORD_ELEMENTS);
01229
01230
01231 for (myCount=wordCount, wordIncr=0; myCount>0;
01232 myCount-=blockWordCount, wordIncr+=blockWordCount) {
01233
01234
01235 blockWordCount = std::min(myCount, MAX_HPID_WORD_ELEMENTS);
01236
01237
01238 dspAddrLocal = dspAddr+ (4*wordIncr);
01239 mdspBlockWrite(hpidAddr, &buffer[wordIncr], blockWordCount, NO_AUTO);
01240 }
01241
01242
01243 hpiaAfterFetch = mdspSingleRead(slvHpia);
01244
01245 if (wordCount == 1) {
01246 hpiaAfterCalc = dspAddr;
01247 }
01248 else {
01249 hpiaAfterCalc = dspAddr+wordCount*4-4;
01250 }
01251
01252
01253
01254
01255
01256
01257 return;
01258 };
01259
01260
01261
01262 void RodModule::resetMasterDsp() throw(RodException&, VmeException &) {
01263 unsigned long value=0;
01264 unsigned long rodRegValue;
01265 clock_t startTime;
01266
01267 rodRegValue = readRodStatusReg(0);
01268 setBit(&value, 1);
01269 if (endianSwap) {
01270 value = endianReverse32(value);
01271 }
01272 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[2], value);
01273 sleep(4000);
01274 rodRegValue = 0;
01275 startTime = clock();
01276 do {
01277 rodRegValue = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[2]);
01278 if ((clock()-startTime)/CLOCKS_PER_SEC > DSP_RESET_TIMEOUT) {
01279 throw RodException("DSP reset timeout in resetMasterDsp(), DSP_RESET_TIMEOUT=",
01280 (long)DSP_RESET_TIMEOUT);
01281 }
01282 }
01283 while (rodRegValue != 0x3e);
01284 rodRegValue = readRodStatusReg(0);
01285
01286 return;
01287 };
01288
01289
01290
01291 void RodModule::resetSlaveDsp(long slaveNumber) throw(RodException&, VmeException &) {
01292 unsigned long value=0;
01293 unsigned long rodRegValue;
01294 clock_t startTime;
01295
01296 setBit(&value, 2+slaveNumber);
01297 if (endianSwap) {
01298 value = endianReverse32(value);
01299 }
01300 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[2], value);
01301 sleep(4000);
01302 rodRegValue = 0;
01303 startTime = clock();
01304 do {
01305 rodRegValue = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[2]);
01306 if ((clock()-startTime)/CLOCKS_PER_SEC > DSP_RESET_TIMEOUT) {
01307 throw RodException("DSP reset timeout in resetSlaveDsp(), DSP_RESET_TIMEOUT=",
01308 (long)DSP_RESET_TIMEOUT);
01309 }
01310 }
01311 while (rodRegValue != 0x3e);
01312
01313 return;
01314 };
01315
01316
01317
01318
01319 void RodModule::resetAllDsps() throw(RodException &, VmeException &) {
01320 unsigned long value=0;
01321 unsigned long rodRegValue;
01322 clock_t startTime;
01323
01324 setBit(&value, 6);
01325 if (endianSwap) {
01326 value = endianReverse32(value);
01327 }
01328 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[2], value);
01329 sleep(4000);
01330 rodRegValue = 0;
01331 startTime = clock();
01332 do {
01333 rodRegValue = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[2]);
01334 if ((clock()-startTime)/CLOCKS_PER_SEC > DSP_RESET_TIMEOUT) {
01335 throw RodException("DSP reset timeout in resetAllDsps(), DSP_RESET_TIMEOUT=",
01336 (long)DSP_RESET_TIMEOUT);
01337 }
01338 }
01339 while (rodRegValue != 0x3e);
01340
01341 return;
01342 };
01343
01344
01345
01346 void RodModule::chipEraseHpi() throw(VmeException &) {
01347 unsigned long value = 0x10;
01348
01349
01350 commonEraseCommandsHpi(MDSP_FLASH_BOTTOM);
01351
01352
01353 mdspSingleWrite(MDSP_FLASH_BOTTOM+(0x5555<<2), value);
01354
01355
01356 sleep(CHIP_ERASE_TIME_MS);
01357 return;
01358 };
01359
01360
01361
01362 void RodModule::sectorErase(unsigned long sectorBaseAddress)
01363 throw(RodException &, VmeException &) {
01364 unsigned long flashBaseAddress, valueD32;
01365 bool busyBit;
01366
01367
01368 switch (m_revision) {
01369 case 0x0f:
01370 case 0x0e:
01371 flashBaseAddress = FPGA_FLASH_REL_ADDR_REVE;
01372 break;
01373 case 0x0b:
01374 case 0x0c:
01375 default:
01376 if ((sectorBaseAddress<FPGA_FLASH_0_BOTTOM)||
01377 (sectorBaseAddress>FPGA_FLASH_2_BOTTOM+FLASH_MEMORY_SIZE)) {
01378 throw RodException("Flash sector base addr out of range, sectorBaseAddress=",
01379 sectorBaseAddress);
01380 }
01381 if (sectorBaseAddress<FPGA_FLASH_1_BOTTOM) {
01382 flashBaseAddress = FPGA_FLASH_0_BOTTOM;
01383 }
01384 else if (sectorBaseAddress<FPGA_FLASH_2_BOTTOM) {
01385 flashBaseAddress = FPGA_FLASH_1_BOTTOM;
01386 }
01387 else flashBaseAddress = FPGA_FLASH_2_BOTTOM;
01388 break;
01389 }
01390
01391 commonEraseCommands(flashBaseAddress);
01392
01393
01394 vmeWriteElementFlash(0x30, sectorBaseAddress, WRITE_COMMAND_HANDSHAKE_BIT);
01395
01396
01397 switch (m_revision ) {
01398 case 0x0f:
01399 case 0x0e:
01400 do {
01401 valueD32 = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[4]);
01402 busyBit = readBit(valueD32, 3);
01403 } while (busyBit);
01404 break;
01405 case 0x0b:
01406 case 0x0c:
01407 default:
01408 sleep(SECTOR_ERASE_TIME_MS);
01409 break;
01410 }
01411
01412 return;
01413 };
01414
01415
01416
01417 void RodModule::writeByteToFlash(unsigned long address, UINT8 data)
01418 throw (RodException &, VmeException &) {
01419 UINT8 readData;
01420 clock_t startTime;
01421 long updateAddress;
01422
01423 if (data!=0xFF) {
01424
01425 vmeWriteElementFlash(data, address, WRITE_DATA_HANDSHAKE_BIT);
01426 updateAddress = 0;
01427 }
01428 else {
01429 updateAddress = 1;
01430 }
01431
01432
01433 startTime = clock();
01434 while(1) {
01435 readData = readByteFromFlash(address, updateAddress);
01436 if (readData == data) return;
01437 else if((clock()-startTime)/CLOCKS_PER_SEC > FLASH_TIMEOUT) {
01438 throw RodException("Flash timeout in writeByteToFlash, FLASH_TIMEOUT=",
01439 (long)FLASH_TIMEOUT);
01440 }
01441 }
01442 return;
01443 };
01444
01445
01446
01447 void RodModule::writeBlockToFlash(unsigned long address, UINT8 *data,
01448 unsigned long numBytes) throw(RodException &, VmeException &) {
01449 unsigned long index, sectorSize;
01450 switch (m_revision) {
01451 case 0x0f:
01452 case 0x0e:
01453 sectorSize = FLASH_SECTOR_SIZE_REVE;
01454 break;
01455 case 0x0b:
01456 case 0x0c:
01457 default:
01458 sectorSize = FLASH_SECTOR_SIZE;
01459 break;
01460 }
01461 for (index=0; index<numBytes; ++index) {
01462 if ((index%sectorSize)==0) {
01463 sectorErase(address+index);
01464 }
01465 writeByteToFlash(address+index, *(data+index));
01466 }
01467 return;
01468 };
01469
01470
01471
01472 void RodModule::writeBlockToFlashHpi(unsigned long address, UINT8 *data,
01473 unsigned long numBytes) throw (RodException &, VmeException &) {
01474 unsigned long index, sectorAddr;
01475 const unsigned long eraseData=0x30;
01476 const unsigned long data1=0xAA;
01477 const unsigned long data2=0x55;
01478 const unsigned long data3=0xA0;
01479 const unsigned long addr1=MDSP_FLASH_BOTTOM+(0x5555<<2);
01480 const unsigned long addr2=MDSP_FLASH_BOTTOM+(0x2AAA<<2);
01481 unsigned long byteRelAddr;
01482 long words;
01483 UINT8 dataVal, verifyVal;
01484 unsigned long longVal, busyVal;
01485
01486 for (index=0; index<numBytes; ++index) {
01487 byteRelAddr = address+index-MDSP_FLASH_BOTTOM;
01488 if ((index%FLASH_SECTOR_SIZE)==0) {
01489
01490
01491 commonEraseCommandsHpi(MDSP_FLASH_BOTTOM);
01492
01493 sectorAddr = MDSP_FLASH_BOTTOM+
01494 (byteRelAddr<<2);
01495 mdspSingleWrite(sectorAddr, eraseData);
01496
01497 sleep(SECTOR_ERASE_TIME_MS);
01498 };
01499
01500
01501 dataVal = *(data+index);
01502 longVal = dataVal&0x000000FF;
01503 if (dataVal != 0xFF) {
01504 mdspSingleWrite(addr1, data1);
01505 mdspSingleWrite(addr2, data2);
01506 mdspSingleWrite(addr1, data3);
01507 mdspSingleWrite(MDSP_FLASH_BOTTOM+(byteRelAddr<<2), longVal);
01508
01509
01510 for (int i=0; i<4000; i++) {
01511 busyVal = mdspSingleRead(MDSP_FLASH_BOTTOM+byteRelAddr);
01512 switch (byteRelAddr%4) {
01513 case 1: busyVal = busyVal >> 8;
01514 break;
01515 case 2: busyVal = busyVal >> 16;
01516 break;
01517 case 3: busyVal = busyVal >> 24;
01518 break;
01519 default: break;
01520 }
01521 busyVal = busyVal & 0x000000FF;
01522 if (busyVal == longVal) break;
01523 }
01524 };
01525 };
01526
01527
01528 words = (numBytes+3)/4;
01529 UINT8 *buffer;
01530 try {
01531 buffer = new UINT8[words*4];
01532 }
01533 catch (std::bad_alloc & ba) {
01534 throw RodException("writeBlockToFlashHpi unable to get buffer.");
01535 }
01536 mdspBlockRead(address, (unsigned long*)buffer, words);
01537 for (index=0; index<numBytes; ++index) {
01538 dataVal = *(data+index);
01539 verifyVal = *(buffer+index);
01540 if (dataVal != verifyVal) {
01541 delete [] buffer;
01542 throw RodException("writeBlockToFlashHpi verify failed. index, data:", index,
01543 dataVal);
01544 };
01545 }
01546 delete [] buffer;
01547 return;
01548 };
01549
01550
01551
01552 UINT8 RodModule::readByteFromFlash(unsigned long address, long updateAddress)
01553 throw (RodException &, VmeException &){
01554 UINT8 dataByte;
01555 unsigned long commandReg;
01556 clock_t startTime;
01557 unsigned long handshakeBitValue = 0;
01558 unsigned long valueD32;
01559
01560 if (updateAddress) {
01561 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[4], address);
01562 }
01563
01564 setBit(&handshakeBitValue, READ_HANDSHAKE_BIT);
01565 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[3], handshakeBitValue);
01566
01567
01568 startTime = clock();
01569 while (1) {
01570 commandReg = m_myVmePort->read32(FPGA_CONTROL_REG_REL_ADDR[3]);
01571 if (0==readBit(commandReg, READ_HANDSHAKE_BIT)) break;
01572 if ((clock()-startTime)>FLASH_TIMEOUT) throw RodException(
01573 "Timeout in readByteFromFlash. Address=", address);
01574 }
01575
01576
01577 valueD32 = m_myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[7]);
01578 dataByte = (UINT8)(valueD32&0xFF);
01579 return dataByte;
01580 };
01581
01582
01583
01584 void RodModule::vmeWriteElementFlash(UINT8 value, unsigned long address,
01585 long handshakeBit) throw (RodException &, VmeException &) {
01586 unsigned long ctrlReg4Val;
01587 unsigned long commandReg;
01588 clock_t startTime;
01589 unsigned long handshakeBitValue=0;
01590
01591 ctrlReg4Val = (value<<24)| address;
01592 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[4], ctrlReg4Val);
01593
01594
01595 setBit(&handshakeBitValue, handshakeBit);
01596 m_myVmePort->write32(FPGA_CONTROL_REG_REL_ADDR[3], handshakeBitValue);
01597
01598
01599 startTime = clock();
01600 while(1) {
01601 commandReg = m_myVmePort->read32(FPGA_CONTROL_REG_REL_ADDR[3]);
01602 if (0==readBit(commandReg, handshakeBit)) break;
01603 if ((clock()-startTime)>FLASH_TIMEOUT) throw RodException(
01604 "Timeout in vmeWriteElementFlash. Address, value=",
01605 address, (unsigned long)value);
01606 }
01607 return;
01608 };
01609
01610
01611
01612 void RodModule::readBlockFromFlash(unsigned long address, UINT8 *buffer,
01613 unsigned long numBytes) throw(RodException &, VmeException &) {
01614 unsigned long index;
01615 for (index=0; index<numBytes; ++index) {
01616 buffer[index] = readByteFromFlash(address+index, 1);
01617 }
01618 return;
01619 };
01620
01621
01622
01623 void RodModule::commonEraseCommands(unsigned long flashBaseAddr)
01624 throw(RodException &, VmeException &) {
01625
01626 const unsigned long addr1 = flashBaseAddr+0x5555;
01627 const unsigned long addr2 = flashBaseAddr+0x2AAA;
01628
01629
01630 vmeWriteElementFlash(0xAA, addr1, WRITE_COMMAND_HANDSHAKE_BIT);
01631
01632
01633 vmeWriteElementFlash(0x55, addr2, WRITE_COMMAND_HANDSHAKE_BIT);
01634
01635
01636 vmeWriteElementFlash(0x80, addr1, WRITE_COMMAND_HANDSHAKE_BIT);
01637
01638
01639 vmeWriteElementFlash(0xAA, addr1, WRITE_COMMAND_HANDSHAKE_BIT);
01640
01641
01642 vmeWriteElementFlash(0x55, addr2, WRITE_COMMAND_HANDSHAKE_BIT);
01643
01644 return;
01645 };
01646
01647
01648
01649 void RodModule::commonEraseCommandsHpi(unsigned long flashBaseAddr)
01650 throw(VmeException &) {
01651
01652 unsigned long buffer;
01653 const unsigned long addr1 = flashBaseAddr+(0x5555<<2);
01654 const unsigned long addr2 = flashBaseAddr+(0x2AAA<<2);
01655
01656
01657 buffer = 0xAA;
01658 mdspSingleWrite(addr1, buffer);
01659
01660
01661 buffer = 0x55;
01662 mdspSingleWrite(addr2, buffer);
01663
01664
01665 buffer = 0x80;
01666 mdspSingleWrite(addr1, buffer);
01667
01668
01669 buffer = 0xAA;
01670 mdspSingleWrite(addr1, buffer);
01671
01672
01673 buffer = 0x55;
01674 mdspSingleWrite(addr2, buffer);
01675
01676 return;
01677 };
01678
01679
01680
01681 unsigned long RodModule::getFlashSectorSize() {
01682 unsigned long sectorSize;
01683 switch (m_revision) {
01684 case 0x0f:
01685 case 0x0e:
01686 sectorSize = FLASH_SECTOR_SIZE_REVE;
01687 break;
01688 case 0x0b:
01689 case 0x0c:
01690 default:
01691 sectorSize = FLASH_SECTOR_SIZE;
01692 break;
01693 }
01694 return sectorSize;
01695 };
01696
01697
01698
01699 void RodModule::sleep(const double milliSecs) {
01700 clock_t start, delay;
01701 delay = CLOCKS_PER_SEC;
01702 delay = clock_t(milliSecs * CLOCKS_PER_SEC / 1000 );
01703
01704 start = clock();
01705 while (clock()-start< delay)
01706 ;
01707 return;
01708 };
01709
01710
01711
01712 unsigned long RodModule::checkSum(const unsigned long *sourceArray, const long wordCount) {
01713 unsigned long result=0;
01714 long i;
01715
01716 for (i=0; i<wordCount; ++i) {
01717 result ^= sourceArray[i];
01718 }
01719 return result;
01720 };
01721
01722
01723
01724 unsigned long RodModule::endianReverse32(const unsigned long inVal) {
01725 unsigned long outVal;
01726 outVal = (inVal & 0x000000ff) << 24;
01727 outVal |= (inVal & 0x0000ff00) << 8;
01728 outVal |= (inVal & 0x00ff0000) >> 8;
01729 outVal |= (inVal & 0xff000000) >> 24;
01730 return outVal;
01731 };
01732
01733 }
01734
01735
01736
01737
01738 std::ostream& operator<<(std::ostream& os, SctPixelRod::RodModule& rod) {
01739 os << "Slot: " << rod.getSlot() << std::endl;
01740 os << "Serial Number:" << rod.getSerialNumber() << std::endl;
01741 os << "Number of slave DSPs: " << rod.getNumSlaves() << std::endl;
01742 os << "Status registers[0-2]: ";
01743 try {
01744 for (int i=0; i<3; i++) {
01745 os << std::hex << rod.readRodStatusReg(i) << " ";
01746 }
01747 os << std::endl;
01748 }
01749 catch (SctPixelRod::VmeException &) {
01750 os << "VmeException while reading ROD status registers. " << std::endl;
01751 }
01752
01753 os << "Command registers[0-1]: ";
01754 try {
01755 for (int i=0; i<2; i++) {
01756 os << std::hex << rod.readRodCommandReg(i) << " ";
01757 }
01758 os << std::endl;
01759 }
01760 catch (SctPixelRod::VmeException &) {
01761 os << "VmeException while reading ROD command registers. " << std::endl;
01762 }
01763
01764 os << "Primitive state: " << rod.getPrimState() << " Text State: " <<
01765 rod.getTextState() << std::dec << std::endl;
01766 return os;
01767 }
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788