namespace std {} using namespace std;
#include <cstdlib>
#include <time.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <fstream>
#include "Rtypes.h"
#include "TEnv.h"
#include "TRegexp.h"
#include "TFile.h"
#include "TDatime.h"
#include "TROOT.h"
#include "TMrbLogger.h"
#include "TMrbDGFData.h"
#include "TMrbDGF.h"
#include "TMrbDGFCommon.h"
#include "TMrbLofDGFs.h"
#include "SetColor.h"
extern TMrbLogger * gMrbLog;
extern TMrbDGFData * gMrbDGFData;
ClassImp(TMrbLofDGFs)
Bool_t TMrbLofDGFs::AddModule(TMrbDGF * Module, Bool_t MultiCrate) {
UInt_t stationBit;
if (this->FindObject(Module->GetName())) {
gMrbLog->Err() << "Module " << Module->GetName() << " (C" << Module->GetCrate() << ".N" << Module->GetStation()
<< ") - already in list" << endl;
gMrbLog->Flush(this->ClassName(), "AddModule");
return(kFALSE);
}
if (fCamac == NULL) {
fCamac = Module->Camac();
fCrate = Module->GetCrate();
fDGFData = Module->Data();
}
if (!MultiCrate) {
stationBit = 1 << (Module->GetStation() - 1);
if (fStationMask & stationBit) {
gMrbLog->Err() << "Module " << Module->GetName() << " (C" << Module->GetCrate() << ".N" << Module->GetStation()
<< ") - station N already occupied" << endl;
gMrbLog->Flush(this->ClassName(), "AddModule");
return(kFALSE);
}
if (fCrate != Module->GetCrate()) {
gMrbLog->Err() << "Module " << Module->GetName() << " (C" << Module->GetCrate() << ".N" << Module->GetStation()
<< ") - different crate" << endl;
gMrbLog->Flush(this->ClassName(), "AddModule");
return(kFALSE);
}
fStationMask |= stationBit;
}
if (MultiCrate) fMultiCrate = kTRUE;
this->Add(Module);
return(kTRUE);
}
Bool_t TMrbLofDGFs::DownloadFPGACode(TMrbDGFData::EMrbFPGAType FPGAType) {
TMrbDGF * dgf;
Bool_t ok;
UInt_t sts;
Int_t size;
UShort_t * dp;
TString sysfip;
UInt_t csrBits;
Int_t subAddr;
TString cnaf;
TArrayI cData;
UInt_t sysBits, fippiDbits, fippiEbits;
if (!this->CheckModules("DownLoadFPGACode")) return(kFALSE);
if (!this->CheckConnect("DownLoadFPGACode")) return(kFALSE);
if (fMultiCrate) {
gMrbLog->Err() << "[" << sysfip
<< " FPGA] List contains modules from different crates - looping over list members ..." << endl;
gMrbLog->Flush(this->ClassName(), "DownloadFPGACode");
ok = kTRUE;
dgf = (TMrbDGF *) this->First();
while (dgf) {
if (!dgf->DownloadFPGACode(FPGAType)) ok = kFALSE;
dgf = (TMrbDGF *) this->After(dgf);
}
return(ok);
}
fBroadCast = fCamac->HasBroadCast(fNsetMask, fNexecCmd);
if (!fBroadCast) {
gMrbLog->Err() << "[" << sysfip
<< " FPGA] No BROADCAST mode available - looping over list members instead ..." << endl;
gMrbLog->Flush(this->ClassName(), "DownloadFPGACode");
ok = kTRUE;
dgf = (TMrbDGF *) this->First();
while (dgf) {
if (!dgf->DownloadFPGACode(FPGAType)) ok = kFALSE;
dgf = (TMrbDGF *) this->After(dgf);
}
return(ok);
}
sysBits = 0;
fippiDbits = 0;
fippiEbits = 0;
if (FPGAType == TMrbDGFData::kSystemFPGA) {
if (!fDGFData->FPGACodeRead(TMrbDGFData::kSystemFPGA)) {
gMrbLog->Err() << "[System FPGA] No FPGA data" << endl;
gMrbLog->Flush(this->ClassName(), "DownloadFPGACode");
return(kFALSE);
}
csrBits = TMrbDGFData::kSystemFPGAReset;
subAddr = A(10);
cnaf = ".A10.F17";
sysfip = "System";
sysBits = fStationMask;
} else {
dgf = (TMrbDGF *) this->First();
while (dgf) {
if (dgf->GetRevision()->GetIndex() == TMrbDGFData::kRevD) fippiDbits |= (1 << (dgf->GetStation() - 1));
else fippiEbits |= (1 << (dgf->GetStation() - 1));
dgf = (TMrbDGF *) this->After(dgf);
}
if (fippiDbits && !fDGFData->FPGACodeRead(TMrbDGFData::kFippiFPGA, TMrbDGFData::kRevD)) {
gMrbLog->Err() << "[Fippi(D) FPGA] No FPGA data" << endl;
gMrbLog->Flush(this->ClassName(), "DownloadFPGACode");
return(kFALSE);
}
if (fippiEbits && !fDGFData->FPGACodeRead(TMrbDGFData::kFippiFPGA, TMrbDGFData::kRevE)) {
gMrbLog->Err() << "[Fippi(E) FPGA] No FPGA data" << endl;
gMrbLog->Flush(this->ClassName(), "DownloadFPGACode");
return(kFALSE);
}
csrBits = TMrbDGFData::kFippiFPGAReset;
subAddr = A(9);
cnaf = ".A9.F17";
sysfip = "Fippi";
}
fCamac->SetBroadCast(fCrate, fStationMask);
if (!this->WriteICSR(csrBits)) return(kFALSE);
this->Wait();
if (sysBits != 0) {
size = fDGFData->GetFPGACodeSize(TMrbDGFData::kSystemFPGA);
dp = (UShort_t *) fDGFData->GetFPGACodeAddr(TMrbDGFData::kSystemFPGA);
cData.Set(size);
this->CopyData(cData, dp, size);
if (gMrbDGFData->IsVerbose()) {
gMrbLog->Out() << "[System FPGA] Setting broadcast mask for crate C" << fCrate << ": 0x"
<< setbase(16) << sysBits << setbase(10) << endl;
gMrbLog->Flush(this->ClassName(), "DownloadFPGACode", setblue);
}
fCamac->SetBroadCast(fCrate, sysBits);
if (fCamac->BlockXfer(fCrate, fNexecCmd, subAddr, F(17), cData, 0, size, kTRUE) == -1) {
gMrbLog->Err() << "[System FPGA] "
<< "C" << fCrate << ".N" << fNexecCmd
<< cnaf << " (pattern=0x" << setbase(16) << sysBits << setbase(10)
<< "): Block xfer failed" << endl;
gMrbLog->Flush(this->ClassName(), "DownloadFPGACode");
return(kFALSE);
}
}
if (fippiDbits != 0) {
size = fDGFData->GetFPGACodeSize(TMrbDGFData::kFippiFPGA, TMrbDGFData::kRevD);
dp = (UShort_t *) fDGFData->GetFPGACodeAddr(TMrbDGFData::kFippiFPGA, TMrbDGFData::kRevD);
cData.Set(size);
this->CopyData(cData, dp, size);
if (gMrbDGFData->IsVerbose()) {
gMrbLog->Out() << "[Fippi(D) FPGA] Setting broadcast mask for crate C" << fCrate << ": 0x"
<< setbase(16) << fippiDbits << setbase(10) << endl;
gMrbLog->Flush(this->ClassName(), "DownloadFPGACode", setblue);
}
fCamac->SetBroadCast(fCrate, fippiDbits);
if (fCamac->BlockXfer(fCrate, fNexecCmd, subAddr, F(17), cData, 0, size, kTRUE) == -1) {
gMrbLog->Err() << "[Fippi(D) FPGA] "
<< "C" << fCrate << ".N" << fNexecCmd
<< cnaf << " (pattern=0x" << setbase(16) << fippiDbits << setbase(10)
<< "): Block xfer failed - ActionCount=-1" << endl;
gMrbLog->Flush(this->ClassName(), "DownloadFPGACode");
return(kFALSE);
}
}
if (fippiEbits != 0) {
size = fDGFData->GetFPGACodeSize(TMrbDGFData::kFippiFPGA, TMrbDGFData::kRevE);
dp = (UShort_t *) fDGFData->GetFPGACodeAddr(TMrbDGFData::kFippiFPGA, TMrbDGFData::kRevE);
cData.Set(size);
this->CopyData(cData, dp, size);
if (gMrbDGFData->IsVerbose()) {
gMrbLog->Out() << "[Fippi(E) FPGA] Setting broadcast mask for crate C" << fCrate << ": 0x"
<< setbase(16) << fippiEbits << setbase(10) << endl;
gMrbLog->Flush(this->ClassName(), "DownloadFPGACode", setblue);
}
fCamac->SetBroadCast(fCrate, fippiEbits);
if (fCamac->BlockXfer(fCrate, fNexecCmd, subAddr, F(17), cData, 0, size, kTRUE) == -1) {
gMrbLog->Err() << "[Fippi(E) FPGA] "
<< "C" << fCrate << ".N" << fNexecCmd
<< cnaf << " (pattern=0x" << setbase(16) << fippiEbits << setbase(10)
<< "): Block xfer failed - ActionCount=-1" << endl;
gMrbLog->Flush(this->ClassName(), "DownloadFPGACode");
return(kFALSE);
}
}
this->Wait();
dgf = (TMrbDGF *) this->First();
ok = kTRUE;
while (dgf) {
sts = dgf->ReadICSR() & csrBits;
if (sts != 0) {
gMrbLog->Err() << "[" << sysfip << " FPGA] "
<< dgf->GetName() << " in C" << dgf->GetCrate() << ".N" << dgf->GetStation()
<< ": Data xfer failed - error 0x" << setbase(16) << sts << setbase(10) << endl;
gMrbLog->Flush(this->ClassName(), "DownloadFPGACode");
ok = kFALSE;
}
sts = dgf->GetStatus();
if (FPGAType == TMrbDGFData::kSystemFPGA) sts |= TMrbDGF::kSystemFPGACodeLoaded;
else sts |= TMrbDGF::kFippiFPGACodeLoaded;
dgf->SetStatus(sts);
dgf = (TMrbDGF *) this->After(dgf);
}
if (gMrbDGFData->IsVerbose()) {
if (ok) {
gMrbLog->Out() << "[" << sysfip << " FPGA] " << "C" << fCrate << ".N" << fNexecCmd
<< ": Code successfully loaded via broadcast" << endl;
gMrbLog->Flush(this->ClassName(), "DownloadFPGACode", setblue);
} else {
gMrbLog->Err() << "[" << sysfip << " FPGA] " << "C" << fCrate << ".N" << fNexecCmd
<< ": error(s) during FPGA download via broadcast" << endl;
gMrbLog->Flush(this->ClassName(), "DownloadFPGACode");
}
}
return(ok);
}
Bool_t TMrbLofDGFs::DownloadFPGACode(const Char_t * FPGAType) {
TMrbNamedX * sysfip;
sysfip = gMrbDGFData->fLofFPGATypes.FindByName(FPGAType, TMrbLofNamedX::kFindUnique | TMrbLofNamedX::kFindIgnoreCase);
if (sysfip == NULL) {
gMrbLog->Err() << "Illegal FPGA type - " << FPGAType << endl;
gMrbLog->Flush(this->ClassName(), "DownloadFPGACode");
return(kFALSE);
}
return(this->DownloadFPGACode((TMrbDGFData::EMrbFPGAType) sysfip->GetIndex()));
}
Bool_t TMrbLofDGFs::DownloadDSPCode(Int_t Retry) {
TMrbDGF * dgf;
Bool_t ok;
Int_t size;
UShort_t * dp;
UInt_t sts;
TArrayI cData;
if (!this->CheckModules("DownLoadDSPCode")) return(kFALSE);
if (!this->CheckConnect("DownLoadDSPCode")) return(kFALSE);
if (fMultiCrate) {
gMrbLog->Err() << "List contains modules from different crates - looping over list members ..." << endl;
gMrbLog->Flush(this->ClassName(), "DownloadDSPCode");
ok = kTRUE;
dgf = (TMrbDGF *) this->First();
while (dgf) {
if (!dgf->DownloadDSPCode()) ok = kFALSE;
dgf = (TMrbDGF *) this->After(dgf);
}
return(ok);
}
fBroadCast = fCamac->HasBroadCast(fNsetMask, fNexecCmd);
if (!fBroadCast) {
gMrbLog->Err() << "No BROADCAST mode available - looping over list members instead ..." << endl;
gMrbLog->Flush(this->ClassName(), "DownloadDSPCode");
ok = kTRUE;
dgf = (TMrbDGF *) this->First();
while (dgf) {
if (!dgf->DownloadDSPCode()) ok = kFALSE;
dgf = (TMrbDGF *) this->After(dgf);
}
return(ok);
}
if (gMrbDGFData->IsVerbose()) {
gMrbLog->Out() << "Setting broadcast mask for crate C" << fCrate << ": 0x"
<< setbase(16) << fStationMask << setbase(10) << endl;
gMrbLog->Flush(this->ClassName(), "DownloadDSPCode", setblue);
}
fCamac->SetBroadCast(fCrate, fStationMask);
if (fDGFData->DSPCodeRead()) {
if (!this->WriteCSR(TMrbDGFData::kDSPReset)) return(kFALSE);
this->Wait();
size = fDGFData->GetDSPCodeSize();
dp = (UShort_t *) fDGFData->GetDSPCodeAddr();
cData.Set(size);
this->CopyData(cData, dp, size);
if (!this->WriteTSAR(1)) return(kFALSE);
if (fCamac->BlockXfer(fCrate, fNexecCmd, A(0), F(16), cData, 2, size - 2, kTRUE) == -1) {
gMrbLog->Err() << "C" << fCrate << ".N" << fNexecCmd
<< ".A0.F16 failed - DSPAddr=1, wc=" << size - 2 << ", ActionCount=-1" << endl;
gMrbLog->Flush(this->ClassName(), "DownloadDSPCode");
return(kFALSE);
}
if (!this->WriteTSAR(0)) return(kFALSE);
if (fCamac->BlockXfer(fCrate, fNexecCmd, A(0), F(16), cData, 0, 2, kTRUE) == -1) {
gMrbLog->Err() << fName << " in C" << fCrate << ".N" << fNexecCmd
<< ".A0.F16 failed - DSPAddr=0, wc=2, ActionCount=-1" << endl;
gMrbLog->Flush(this->ClassName(), "DownloadDSPCode");
return(kFALSE);
}
this->Wait();
dgf = (TMrbDGF *) this->First();
ok = kTRUE;
while (dgf) {
if (dgf->ReadCSR() & TMrbDGFData::kDSPError) {
if (!dgf->DownloadDSPCode(Retry, kTRUE)) ok = kFALSE;
}
sts = dgf->GetStatus();
sts |= TMrbDGF::kDSPCodeLoaded;
dgf->SetStatus(sts);
dgf = (TMrbDGF *) this->After(dgf);
}
if (gMrbDGFData->IsVerbose()) {
if (ok) {
gMrbLog->Out() << "C" << fCrate << ".N" << fNexecCmd
<< ": DSP code successfully loaded via broadcast (" << size << " words)" << endl;
gMrbLog->Flush(this->ClassName(), "DownloadDSPCode", setblue);
} else {
gMrbLog->Err() << "C" << fCrate << ".N" << fNexecCmd
<< ": error(s) during DSP download via broadcast" << endl;
gMrbLog->Flush(this->ClassName(), "DownloadDSPCode");
}
}
return(ok);
} else {
gMrbLog->Err() << "No DSP data" << endl;
gMrbLog->Flush(this->ClassName(), "DownloadDSPCode");
return(kFALSE);
}
}
Bool_t TMrbLofDGFs::FPGACodeLoaded(TMrbDGFData::EMrbFPGAType FPGAType) {
TMrbDGF * dgf;
UInt_t bit = (FPGAType == TMrbDGFData::kSystemFPGA) ?
TMrbDGF::kSystemFPGACodeLoaded :
TMrbDGF::kFippiFPGACodeLoaded;
dgf = (TMrbDGF *) this->First();
while (dgf) {
if ((dgf->GetStatus() & bit) == 0) return(kFALSE);
dgf = (TMrbDGF *) this->After(dgf);
}
return(kTRUE);
}
Bool_t TMrbLofDGFs::FPGACodeLoaded(const Char_t * FPGAType) {
TMrbNamedX * sysfip;
sysfip = gMrbDGFData->fLofFPGATypes.FindByName(FPGAType, TMrbLofNamedX::kFindUnique | TMrbLofNamedX::kFindIgnoreCase);
if (sysfip == NULL) {
gMrbLog->Err() << "Illegal FPGA type - " << FPGAType << endl;
gMrbLog->Flush(this->ClassName(), "FPGACodeLoaded");
return(kFALSE);
}
return(this->FPGACodeLoaded((TMrbDGFData::EMrbFPGAType) sysfip->GetIndex()));
}
Bool_t TMrbLofDGFs::DSPCodeLoaded() {
TMrbDGF * dgf;
dgf = (TMrbDGF *) this->First();
while (dgf) {
if ((dgf->GetStatus() & TMrbDGF::kDSPCodeLoaded) == 0) return(kFALSE);
dgf = (TMrbDGF *) this->After(dgf);
}
return(kTRUE);
}
Bool_t TMrbLofDGFs::CheckConnect(const Char_t * Method) {
TMrbDGF * dgf;
Bool_t ok;
dgf = (TMrbDGF *) this->First();
ok = kTRUE;
while (dgf) {
if (!dgf->IsConnected()) {
gMrbLog->Err() << dgf->GetTitle() << " - assigned to host " << dgf->GetCamacHost() << ", but NOT connected" << endl;
gMrbLog->Flush(this->ClassName(), Method);
ok = kFALSE;
}
dgf = (TMrbDGF *) this->After(dgf);
}
return(ok);
}
Bool_t TMrbLofDGFs::CheckModules(const Char_t * Method) {
if (fStationMask == 0) {
gMrbLog->Err() << "List of DGF modules is empty" << endl;
gMrbLog->Flush(this->ClassName(), Method);
return(kFALSE);
}
return(kTRUE);
}
TMrbDGF::EMrbWaitStatus TMrbLofDGFs::WaitActive(Int_t Timeout) {
UInt_t csr;
time_t start;
start = time(NULL);
sleep(1);
while ((time(NULL) - start) < Timeout) {
TMrbDGF * dgf = (TMrbDGF *) this->First();
Bool_t ok = kTRUE;
while (dgf) {
csr = dgf->ReadCSR();
if (csr == 0xffffffff || (csr & TMrbDGFData::kActive) != 0) ok = kFALSE;
gSystem->ProcessEvents();
if (this->IsAborted() || dgf->IsAborted()) {
gMrbLog->Err() << "Aborted after " << (time(NULL) - start) << " secs. Stopping current run." << endl;
gMrbLog->Flush(this->ClassName(), "WaitActive");
return(TMrbDGF::kWaitAborted);
}
dgf = (TMrbDGF *) this->After(dgf);
}
if (ok) return(TMrbDGF::kWaitOk);
}
gMrbLog->Err() << "Timed out after " << Timeout << " secs" << endl;
gMrbLog->Flush(this->ClassName(), "WaitActive");
TMrbDGF * dgf = (TMrbDGF *) this->First();
while (dgf) {
csr = dgf->ReadCSR();
if (csr == 0xffffffff) {
gMrbLog->Err() << dgf->GetName() << " in C" << dgf->GetCrate() << ".N" << dgf->GetStation()
<< ": Unexpected error." << endl;
gMrbLog->Flush(this->ClassName(), "WaitActive");
} else if ((csr & TMrbDGFData::kActive) != 0) {
gMrbLog->Err() << dgf->GetName() << " in C" << dgf->GetCrate() << ".N" << dgf->GetStation()
<< ": Still active." << endl;
gMrbLog->Flush(this->ClassName(), "WaitActive");
}
dgf = (TMrbDGF *) this->After(dgf);
}
return(TMrbDGF::kWaitTimedOut);
}
Bool_t TMrbLofDGFs::WriteICSR(UInt_t Data) {
Int_t cVal = (Int_t) Data;
if (!fCamac->ExecCnaf(fCrate, fNexecCmd, A(8), F(17), cVal, kTRUE)) {
gMrbLog->Err() << fName << " in C" << fCrate << ".N" << fNexecCmd << ".A8.F17 failed" << endl;
gMrbLog->Flush(this->ClassName(), "WriteICSR");
return(kFALSE);
}
return(kTRUE);
}
Bool_t TMrbLofDGFs::WriteCSR(UInt_t Data) {
Int_t cVal = (Int_t) Data;
if (!fCamac->ExecCnaf(fCrate, fNexecCmd, A(0), F(17), cVal, kTRUE)) {
gMrbLog->Err() << fName << " in C" << fCrate << ".N" << fNexecCmd << ".A0.F17 failed" << endl;
gMrbLog->Flush(this->ClassName(), "WriteCSR");
return(kFALSE);
}
return(kTRUE);
}
Bool_t TMrbLofDGFs::WriteTSAR(UInt_t Addr) {
Int_t cVal = (Int_t) Addr;
if (!fCamac->ExecCnaf(fCrate, fNexecCmd, A(1), F(17), cVal, kTRUE)) {
gMrbLog->Err() << fName << " in C" << fCrate << ".N" << fNexecCmd
<< ".A1.F17 failed - DSPAddr=0x" << setbase(16) << Addr << setbase(10) << endl;
gMrbLog->Flush(this->ClassName(), "WriteTSAR");
return(kFALSE);
}
return(kTRUE);
}
Bool_t TMrbLofDGFs::WriteWCR(Int_t Data) {
Int_t cVal = Data;
if (!fCamac->ExecCnaf(fCrate, fNexecCmd, A(2), F(17), cVal, kTRUE)) {
gMrbLog->Err() << fName << " in C" << fCrate << ".N" << fNexecCmd << ".A2.F17 failed" << endl;
gMrbLog->Flush(this->ClassName(), "WriteWCR");
return(kFALSE);
}
return(kTRUE);
}