Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals | Related Pages

FlashLoadCrate.cxx

00001 //--------------------------FlashLoadCrate-----------------------------
00013 #include <iostream>
00014 #include <fstream>
00015 #include <string>
00016 using namespace std;
00017 
00018 #include <ctype.h>
00019 
00020 #include "RodModule.h"
00021 
00022 #include "primParams.h"
00023 #include "RCCVmeInterface.h"
00024 #include "parameters.h"
00025 
00026 int main(int argc, char *argv[]) {
00027 
00028 using namespace SctPixelRod;
00029 
00030   unsigned long serialNumber[22], masked1, masked2, rodRevision[22];
00031   VmePort *myVmePort;
00032   
00033   std::string binFileName("");
00034   ifstream binFile;
00035   unsigned long selectAddr;
00036   unsigned long flashAddr;
00037   int fileSize;
00038   int selectSize;
00039   int iselect = 0;
00040   int safeMode = false;
00041 
00042   const unsigned long flashStartE[5]={0x1400000, 0xe00000, 0xe80000, 0xf00000, 0xf80000};
00043   const long flashSizeE[5] = {0, 495204, 495212, 336680, 336680};
00044 
00045   std::string flashName[5] = {"Master DSP", "ROD Controller", "Formatter",
00046        "Event Fragment Builder", "Router"};
00047 
00048   int slot = -1;
00049   int numRods = 0;
00050   int rodUpdate[22];
00051   std::string option;
00052   unsigned long baseAddress;
00053 //
00054 // Check for safe mode option being requested for MDSP loading.
00055 //
00056 
00057   if (argc > 1) {
00058     for (int i=1; i<argc; i++) {
00059       option = argv[i];
00060       if (option[0] != '-') break;
00061       switch (option[1]) {
00062         case 'f': {
00063           safeMode = true;
00064           break;
00065         }
00066         default: {
00067           break;
00068         }
00069       }
00070     }
00071   }
00072 
00073 //
00074 // Initialise some arrays.
00075 //
00076   for(int i=0;i<22;i++) {
00077     rodUpdate[i] = 0;
00078     rodRevision[i] = 0;
00079     serialNumber[i] = 0;
00080   }
00081 
00082 // Create VME interface  - this remains until the end of the program.
00083 //
00084   RCCVmeInterface *vme1 = new RCCVmeInterface();
00085 
00086 //
00087 // Loop over RODs, identifying Rev E/F RODs for flashing.
00088 //
00089   for(slot=5; slot<=21; slot++) {
00090    if(slot != 13) {  //Skip the TIM in slot 13.
00091     baseAddress = slot << 24;
00092 
00093 // Create RodModule and initialize it
00094     RodModule* rod0 = new RodModule(baseAddress, mapSize, *vme1, numSlaves);
00095     myVmePort = rod0->getVmePort();
00096 
00097     try {
00098 // Read the FPGA Status Register 6 (counting from 0)
00099       serialNumber[slot] = myVmePort->read32(FPGA_STATUS_REG_REL_ADDR[6]);
00100       masked1 = serialNumber[slot]&0xFF000000;
00101       masked2 = serialNumber[slot]&0x000000FF;
00102       if (0xad000000 == masked1) {
00103 // Get the revision level and serial number of the ROD.
00104         rodRevision[slot] = (serialNumber[slot]&0x00FF0000)>>16;
00105         serialNumber[slot] = serialNumber[slot]&0x3FF;
00106 //If this is a Rev E or Rev F, mark the ROD for updating.
00107     if ((rodRevision[slot] == 0xE) || (rodRevision[slot] == 0xF)) {
00108           numRods++;
00109       rodUpdate[slot] = 1;
00110         }
00111       }
00112       else if (0x000000ad == masked2) {
00113         cout << "Byte order wrong, ROD in slot: " << slot << endl;
00114       }
00115       else {
00116         cout << "Sanity check failed, ROD in slot: " << slot << endl;
00117       }
00118     } catch(BaseException &b) {
00119       cout << "Exception touching ROD in slot:\n" << slot << b << endl;
00120     }
00121 
00122 // Delete the ROD object - avoids having up to 16 of these created at once.
00123     delete rod0;
00124    }
00125   }    //end of loop over slot
00126 //
00127 // Report our findings - list the RODs to be updated, and those which will not.
00128 //
00129   cout << endl;
00130   cout << "Rev E/F RODs in slots: ";
00131   for (int i=5;i<=21;i++) {
00132     if (rodUpdate[i] == 1) {
00133       cout << i << " ";
00134     }
00135   }
00136   cout << " will be updated" << endl;
00137 //
00138   cout << "Other revision RODs in slots: ";
00139   for (int i=5;i<=21;i++) {
00140     if ((i!=13) && (rodUpdate[i] == 0)) {
00141       cout << i << " ";
00142     }
00143   }
00144   cout << " will NOT be updated" << endl << endl;
00145 //
00146 // Now do the update on all RevE and F boards.
00147 //
00148 // Do MDSP flash first, and keep separate from the loop over VHDL flash, as
00149 // the details are different.
00150 //
00151 // Check whether we do want to update the MDSP flash.
00152     option[0] = 'n';
00153     cout << "==>Updating " << flashName[iselect] << " flash<==" << endl;
00154     cout << "Do you wish to update this flash (Y/n)? " <<endl;
00155     getline(cin,option);
00156     if ((option[0] == 'y') || (option[0] == 'Y') || (option.size() == 0)){
00157       cout << "Flash will be updated" << endl;
00158       selectAddr = flashStartE[iselect];
00159       selectSize = flashSizeE[iselect];
00160 //
00161 // Get the file information
00162 //
00163     cout << "Enter binary file name, including extension: ";
00164     getline(cin,binFileName);
00165 
00166     binFile.open(binFileName.c_str(), ios::binary);
00167     if (!binFile.is_open()) {
00168       cout << "Unable to open binary file." << endl;
00169       exit(1);
00170     }
00171 
00172 // Get size of file
00173     binFile.seekg(0, ios::end);           // go to end of file
00174     fileSize = binFile.tellg();          // file size given by current location
00175     binFile.seekg(0, ios::beg);          // go back to beginning of file
00176 
00177 // Create a buffer and read file into itprmSize = fileSize
00178 
00179     UINT8 * buffer;
00180     try {
00181       buffer = new UINT8[fileSize];
00182     }
00183     catch (std::bad_alloc & ba) {
00184       cout << "Unable to allocate buffer for binary file." << endl;
00185       exit(2);
00186     }
00187     binFile.read((char *)buffer, fileSize);
00188 
00189     cout << "Read file of size " << fileSize << endl;
00190 //
00191     option[0] = 'n';
00192     cout << flashName[iselect] << " flash will be updated with file "
00193          << binFileName << endl;
00194     cout << "Are you sure that you want to update this flash (y/n)? " <<endl;
00195     getline(cin,option);
00196     if ((option[0] == 'y') || (option[0] == 'Y')){
00197       cout << "Flash will be updated" << endl;
00198 //
00199 // Do we use safe mode or not??
00200 //
00201       for(slot=5;slot<22;slot++) {
00202         if(rodUpdate[slot] == 1) {    //Only do this if this ROD is to be updated
00203           cout << "Updating ROD in slot " << slot << ",serial number "
00204             << (serialNumber[slot]&0xFF) << endl;
00205 // Create RodModule and initialize it
00206           baseAddress = slot <<24;
00207           RodModule* rod0 = new RodModule(baseAddress, mapSize, *vme1, numSlaves);
00208           if(!safeMode) {
00209             try{
00210               rod0->initialize();
00211             }
00212             catch (HpiException &h) {
00213               cout << "HPI exception initialising ROD\n";
00214               hex(cout);
00215               cout << h.getDescriptor() << '\n';
00216               cout << "calcAddr: " << h.getCalcAddr() << ", readAddr: " <<
00217                 h.getReadAddr() << '\n';
00218               dec(cout);
00219 
00220               cout << "Try the \"safe\" mode (-f)\n";
00221               return 1;
00222             }
00223             catch (BaseException &b) {
00224               cout << "Other exception initialising ROD\n";
00225               cout << b << endl;
00226 
00227               cout << "Try the \"safe\" mode (-f)\n";
00228               return 1;
00229             };
00230           } else {   // Safe mode (doesn't try to talk to MDSP (for when the MDSP is corrupt))
00231             try {
00232               unsigned long int fpgaHold = 0x40;
00233               unsigned long int mdspReset = 0x2;
00234 
00235               cerr << "Put FPGAs on reset hold\n";
00236 // Put FPGAs on hold
00237               rod0->hpiLoad(FPGA_CONTROL_REG_REL_ADDR[1], fpgaHold);
00238               rod0->sleep(1000);
00239 // Reset MDSP
00240               rod0->hpiLoad(FPGA_CONTROL_REG_REL_ADDR[2], mdspReset);
00241 
00242               rod0->sleep(1000);
00243 
00244               unsigned long hpicValue = 0x00010001;
00245               rod0->hpiLoad(HPIC, hpicValue);
00246 
00247               rod0->sleep(1000);
00248 // mdspSingleRead/Write use HPID not HPID++ (not allowed)
00249 
00250               cerr << "Read from EMIF (1)\n";
00251               for(unsigned long addr = 0x01800000; addr < 0x0180001c; addr+=4) {
00252                 unsigned long val = rod0->mdspSingleRead(addr);
00253                 cerr << "0x" << hex << addr << ": 0x" << val << dec << endl;
00254               }
00255 
00256               rod0->sleep(100);
00257 
00258               cerr << "Write CE space setup\n";
00259               rod0->mdspSingleWrite(0x01800004, 0xffff3f03);
00260               rod0->mdspSingleWrite(0x01800008, 0x00000040);
00261               rod0->mdspSingleWrite(0x01800010, 0xffff3f33);
00262               rod0->mdspSingleWrite(0x01800014, 0xffff3f33);
00263 
00264               rod0->sleep(500);
00265 
00266               cerr << "Read from EMIF (2)\n";
00267 
00268 // mdspSingleRead/Write use HPID not HPID++ (not allowed)
00269 
00270               for(unsigned long addr = 0x01800000; addr < 0x0180001c; addr+=4) {
00271                 unsigned long val = rod0->mdspSingleRead(addr);
00272                 cerr << "0x" << hex << addr << ": 0x" << val << dec << endl;
00273               }
00274             }
00275             catch (BaseException &b) {
00276               cout << "Exception \"initing\" ROD:\n" << b << endl;
00277               exit(0);
00278             }
00279 
00280             rod0->sleep(3000);
00281           }
00282 
00283 // write buffer to MDSP flash memory
00284           try {
00285             flashAddr = selectAddr;
00286             rod0->writeBlockToFlashHpi(flashAddr, buffer, fileSize);
00287 
00288             cout << fileSize << " bytes written to the MDSP flash memory"<< endl;
00289           } catch (VmeException &v) {
00290             cout << "VmeException creating Writing flash." << endl;
00291             cout << "ErrorClass = " << v.getErrorClass() << endl;
00292             cout << "ErrorCode = " << v.getErrorCode() << endl;
00293           } catch (RodException &r) {
00294             cout << r.getDescriptor() <<", " << r.getData1() << ", " 
00295                << r.getData2() << '\n';
00296           }
00297 
00298 // Clean up before exiting
00299           delete rod0;
00300         }
00301       }       // end of loop over slot
00302     }         //confirmatory if!!
00303 //Tidy up the buffer and close the file
00304   delete [] buffer;
00305   binFile.close();
00306   }
00307   cout << endl << endl;
00308 //
00309 // Loop over the flash to update in the outer loop (then the binary file need
00310 // only be identified once).
00311 //
00312   for(iselect=1;iselect<5;iselect++) {
00313     option[0] = 'n';
00314     cout << "==>Updating " << flashName[iselect] << " flash<==" << endl;
00315     cout << "Do you wish to update this flash (Y/n)? " <<endl;
00316     getline(cin,option);
00317     if ((option[0] == 'y') || (option[0] == 'Y') || (option.size() == 0)){
00318       cout << "Flash will be updated" << endl;
00319       selectAddr = flashStartE[iselect];
00320       selectSize = flashSizeE[iselect];
00321       cout << "Enter binary file name, including extension: ";
00322       getline(cin,binFileName);
00323 
00324       binFile.open(binFileName.c_str(), ios::binary);
00325 
00326       if (!binFile.is_open()) {
00327         cout << "Unable to open binary file." << endl;
00328       }
00329       else {
00330 
00331 // Get size of file
00332         binFile.seekg(0, ios::end);      // go to end of file
00333         fileSize = binFile.tellg();      // file size given by current location
00334         binFile.seekg(0, ios::beg);      // go back to beginning of file
00335         if (fileSize != selectSize) {
00336         cout << "File size is incorrect. Expected: " << dec << selectSize 
00337         << " Found: " << dec << fileSize << endl;
00338         exit(3);
00339         }
00340 
00341 // Create a buffer and read file into it
00342         UINT8 * buffer;
00343         try {
00344           buffer = new UINT8[fileSize];
00345         }
00346         catch (std::bad_alloc & ba) {
00347           cout << "Unable to allocate buffer for binary file." << endl;
00348           exit(2);
00349         }
00350         binFile.read((char *)buffer, fileSize);
00351 //
00352         option[0] = 'n';
00353         cout << flashName[iselect] << " flash will be updated with file "
00354            << binFileName << endl;
00355         cout << "Are you sure that you want to update this flash (y/n)? " <<endl;
00356         getline(cin,option);
00357         if ((option[0] == 'y') || (option[0] == 'Y')){
00358           cout << "Flash will be updated" << endl;
00359 // write buffer to flash - loop over RODs at this point.
00360           for(slot=5;slot<22;slot++) {
00361             if(rodUpdate[slot] == 1) {      //Only if this ROD should be updated.
00362               cout << "Updating ROD in slot " << slot << ", serial number "
00363                 << (serialNumber[slot]&0xFF) << endl;
00364 // Create RodModule and initialize it
00365               baseAddress = slot << 24;
00366               RodModule* rod0 = new RodModule(baseAddress, mapSize, *vme1, numSlaves);
00367               try{
00368                 rod0->initialize();
00369               }
00370               catch (HpiException *h) {
00371                 hex(cout);
00372                 cout << h->getDescriptor() << '\n';
00373                 cout << "calcAddr: " << h->getCalcAddr() << ", readAddr: " <<
00374                   h->getReadAddr() << '\n';
00375                 dec(cout);
00376               };
00377 
00378               try {
00379                 flashAddr = selectAddr;
00380                 rod0->writeBlockToFlash(flashAddr, buffer, fileSize);
00381 
00382                 cout << dec << selectSize << " bytes written to the "
00383                   << flashName[iselect] << " flash memory" << endl;
00384               } catch(BaseException &b) {
00385                 cout << "******* Exception during FLASH upload!********\n";
00386                 cout << b << endl;
00387               }
00388               delete rod0;
00389             }
00390           }       //end of loop over slot
00391         }       // end of confirmatory if
00392 // Clean up before exiting this flash update.
00393         delete [] buffer;
00394     binFile.close();    //close the file
00395       }
00396     }
00397     else {
00398       cout << "Update of this flash is skipped" << endl;
00399     }
00400 //
00401   cout << endl << endl;
00402   }     // end of loop over select
00403 //
00404 // On exit, delete the VME object.
00405   delete vme1;
00406 
00407   return 0;  
00408 }
00409 
00410 

Generated on Thu Dec 22 20:17:02 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5