#include "DTrigger.h"
///////////////////////////////////////////////////////////////////////////////
// CERES trigger
//
// DTrigger describes the CERES trigger. A DTrigger object has a number
// of pointers to specific VME modules. The member functions translate
// generic commands (like "enable abort") to hardware operations (like
// "enable channel 2 in DL633 coincidence pointed to by *fAboinp").
//
// Nomenclature used to describe communication with hardware:
//
// module - VME module
// module object - objects for communication with modules, like *fLogic0
// write - write from the code to VME memory
// read - copy VME memory to object
// get - copy from object to code
//
// Trigger signals:
//
// FLT - first level trigger
// SLT - second level trigger
// Abort - an abort is an alternative to SLT after a FLT
// Busy - detectors set busy after they received a FLT; these
// busies are OR'ed; end of this OR generates Reset
// Reset - resets FLT level and then restores FLT gate
///////////////////////////////////////////////////////////////////////////////
#ifdef COMPIL
ClassImp(DTrigger)
#endif
#include "TCanvas.h"
#include "TPaveText.h"
//*****************************************************************************
DTrigger::DTrigger() : TObject() {
// Create objects corresponding to VME modules, and store the pointers
// to these objects on the object array *fModuleList.
cout<<"constructing DTriggern";
fModuleList = new TObjArray();
fModuleList->Add(fLogic0 = new DLogic("pattern generator", 0xd0000000));
fModuleList->Add(fLogic1 = new DLogic("lookup table", 0xd0010000));
fModuleList->Add(fDown[0] = new DDownscaler("physics", 0xd0020000));
fModuleList->Add(fDown[1] = new DDownscaler("mt", 0xd0030000));
fModuleList->Add(fDown[2] = new DDownscaler("cal", 0xd0080000));
fModuleList->Add(fDisc = new DDisc("SLT SDD", 0xd00b0000));
fModuleList->Add(fDown2 = new DDownscaler("SLT SDD", 0xd00c0000));
fModuleList->Add(fFltinp = new DDL633("FLT input logic", 0xcf000060));
fModuleList->Add(fFltout = new DDL634("FLT fanout", 0xcf000040));
fModuleList->Add(fAboinp = new DDL633("Abort input logic", 0xcf000020));
fModuleList->Add(fAboout = new DDL634("Abort fanout", 0xcf000000));
fModuleList->Add(fBusy[0] = new DDL633("Busy collection 1/2", 0xcf001060));
fModuleList->Add(fBusy[1] = new DDL633("Busy collection 2/2", 0xcf001040));
fModuleList->Add(fBusyor = new DDL633("Busy 1 or 2", 0xcf001020));
fModuleList->Add(fBusyout = new DDL634("Busy fanout", 0xcf001000));
fModuleList->Add(fBusypat[0] = new DDL631("Busy pattern 1/2", 0xcf002060));
fModuleList->Add(fBusypat[1] = new DDL631("Busy pattern 2/2", 0xcf002040));
fModuleList->Add(fScaler0 = new DScaler("ECL scaler", 0xd0090000));
fModuleList->Add(fScaler1 = new DScaler("NIM scaler", 0xd00a0000));
printf("%d modulesn",fModuleList->GetLast()+1);
}
//-----------------------------------------------------------------------------
DTrigger::~DTrigger() {
cout<<"destroying DTriggern";
delete fModuleList;
}
//-----------------------------------------------------------------------------
void DTrigger::ResetModules() {
// Call ResetModule for every VME module of fModuleList
TObject *elem;
TIterator *iter;
iter = fModuleList->MakeIterator();
while ( (elem = iter->Next()) > 0) ((DModule*) elem)->ResetModule();
}
//-----------------------------------------------------------------------------
void DTrigger::Initialize() {
// Setup these parameters of VME modules which are fixed, i.e. not
// supposed to be changed by the end-user, and thus are not accesible
// via GUI.
Int_t i;
// pattern generator: transparent mode
fLogic0->ExtClock();
fLogic0->LogicMode(0);
fLogic0->LogicMode(1);
fLogic0->WriteRAM(0,"i");
fLogic0->WriteRAM(1,"i");
// lookup table: standard setup
fLogic1->LogicMode(0);
fLogic1->LogicMode(1);
fLogic1->DefineLogic(0, 0, "[0] & [1]");
fLogic1->DefineLogic(0, 3, "[0] & [1]");
fLogic1->DefineLogic(0, 1, "[0] & [1] & [2]");
fLogic1->DefineLogic(0, 4, "[0] & [1] & [2]");
fLogic1->DefineLogic(0, 2, "[0] & [1] & [2] & [3]");
fLogic1->DefineLogic(0, 5, "[0] & [1] & [2] & [3]");
fLogic1->DefineLogic(0, 6, "[0]");
fLogic1->DefineLogic(0, 7, "[0] & [4]");
fLogic1->WriteRAM(1, (UShort_t) 0);
fLogic1->DefineLogic(1, 0, "![1]");
fLogic1->DefineLogic(1, 1, "[1]");
// FLT OR
fFltinp->Enable(0);
fFltinp->Enable(1);
fFltinp->Enable(2);
fFltinp->Enable(3);
fFltinp->OrLogic(0);
fFltinp->OrLogic(1);
fFltinp->OrLogic(2);
fFltinp->OrLogic(3);
fFltout->Inv(0);
fFltout->Inv(1);
fFltout->Inv(2);
fFltout->Norm(3);
// Abort OR
fAboinp->Disable(3);
fAboinp->OrLogic(0);
fAboinp->OrLogic(1);
fAboinp->OrLogic(2);
fAboinp->OrLogic(3);
// busy collection
for (i=0; i<4; i++) {
fBusyor->Disable(i);
fBusy[0]->OrLogic(i);
fBusy[1]->OrLogic(i);
fBusyor->OrLogic(i);
fBusyout->Norm(i);
}
fBusyor->Enable(0);
fBusyor->Enable(1);
fBusyout->Inv(0);
fBusyout->Inv(1);
// busy pattern
fBusypat[0]->FlipFlopsMasked();
fBusypat[1]->FlipFlopsMasked();
}
//-----------------------------------------------------------------------------
void DTrigger::Load(char *filename) {
// Load setup from file. Setup means here only the dynamic part
// of setup, i.e. the parameters which can be changed by the end-user.
Int_t i, j;
UShort_t ram[256];
TString buf;
int old_options;
Int_t temp;
ifstream inpfile(filename, ios::in);
if (!inpfile) {
cout << "DTrigger: cannot open file " << filename << endl;
return;
}
while (buf.ReadLine(inpfile)) {
if (buf.Contains("physics logic")) {
old_options = inpfile.flags(ios::hex);
for (i=0; i<16; i++) {
for (j=0; j<16; j++) {
inpfile >> ram[16*i+j];
}
}
inpfile.flags(old_options);
fLogic1->WriteRAM(0, ram);
}
if (buf.Contains("MTCAL logic")) {
old_options = inpfile.flags(ios::hex);
for (i=0; i<16; i++) {
for (j=0; j<16; j++) {
inpfile >> ram[16*i+j];
}
}
inpfile.flags(old_options);
fLogic1->WriteRAM(1, ram);
}
if (buf.Contains("FLT")) {
buf.ReplaceAll("FLT", "");
Int_t nflt = atoi(buf.Data());
for (i=0; i<nflt; i++) {
inpfile >> temp;
inpfile >> temp;
if (temp) EnableFLT(i);
else DisableFLT(i);
inpfile >> temp;
WriteFLTDownscal(i, temp);
}
}
if (buf.Contains("Abort")) {
buf.ReplaceAll("Abort", "");
Int_t nabort = atoi(buf.Data());
for (i=0; i<nabort; i++) {
inpfile >> temp;
inpfile >> temp;
if (temp) EnableAbort(i);
else DisableAbort(i);
}
}
if (buf.Contains("SDD multiplicity")) {
for (i=0; i<4; i++) {
inpfile >> temp;
inpfile >> temp;
if (temp) EnableSDDMult(i);
else DisableSDDMult(i);
inpfile >> temp;
WriteSDDMultThr(i, temp);
inpfile >> temp;
WriteSDDMultDownscal(i, temp);
}
}
if (buf.Contains("Busy")) {
buf.ReplaceAll("Busy", "");
Int_t nbusy = atoi(buf.Data());
for (i=0; i<nbusy; i++) {
inpfile >> temp;
inpfile >> temp;
if (temp) EnableBusy(i);
else DisableBusy(i);
}
}
}
return;
}
//-----------------------------------------------------------------------------
void DTrigger::Save(char *filename) {
// Save setup on file. Setup means here only the dynamic part of setup,
// i.e. the parameters which can be changed by the end-user.
Int_t i,j;
UShort_t* ram;
FILE *outfile;
outfile = fopen(filename,"w");
// physics logic
fprintf(outfile,"physics logicn");
ram = fLogic1->GetRAM(0);
for (i=0; i<16; i++) {
for (j=0; j<16; j++) fprintf(outfile, "%2x ", ram[16*i+j] & 0xff);
fprintf(outfile, "n");
}
fprintf(outfile, "n");
// MT/CAL logic
fprintf(outfile,"MTCAL logicn");
ram = fLogic1->GetRAM(1);
for (i=0; i<16; i++) {
for (j=0; j<16; j++) fprintf(outfile, "%2x ", ram[16*i+j] & 0xff);
fprintf(outfile, "n");
}
fprintf(outfile, "n");
// FLT
fprintf(outfile,"FLT %dn", NFLT);
for (i=0; i<NFLT; i++) {
fprintf(outfile, "%2d %2d %6dn", i, IsEnabledFLT(i), GetFLTDownscal(i));
}
fprintf(outfile, "n");
// Abort
fprintf(outfile,"Abort %dn", NABORT);
for (i=0; i<NABORT; i++) {
fprintf(outfile, "%2d %2dn", i, IsEnabledAbort(i));
}
fprintf(outfile, "n");
// SDD multiplicity
fprintf(outfile,"SDD multiplicityn");
for (i=0; i<4; i++) {
fprintf(outfile, "%2d %2d %6d %6dn", i, IsEnabledSDDMult(i),
GetSDDMultThr(i), GetSDDMultDownscal(i));
}
fprintf(outfile, "n");
// Busy
fprintf(outfile,"Busy %dn", NBUSY);
for (i=0; i<NBUSY; i++) {
fprintf(outfile, "%2d %2dn", i, IsEnabledBusy(i));
}
fprintf(outfile, "n");
fclose(outfile);
}
//-----------------------------------------------------------------------------
void DTrigger::EnableBBP() {
// Enable beam before-protection.
fLogic1->AddToLogic(0, 0, "&![6]");
fLogic1->AddToLogic(0, 1, "&![6]");
fLogic1->AddToLogic(0, 2, "&![6]");
}
//-----------------------------------------------------------------------------
void DTrigger::EnableIBP() {
// Enable interaction before-protection.
fLogic1->AddToLogic(0, 0, "&![7]");
fLogic1->AddToLogic(0, 1, "&![7]");
fLogic1->AddToLogic(0, 2, "&![7]");
}
//-----------------------------------------------------------------------------
void DTrigger::DisableBBP() {
// Disable beam before-protection.
fLogic1->RemoveFromLogic(0, 0, "&![6]");
fLogic1->RemoveFromLogic(0, 1, "&![6]");
fLogic1->RemoveFromLogic(0, 2, "&![6]");
}
//-----------------------------------------------------------------------------
void DTrigger::DisableIBP() {
// Disable interaction before-protection.
fLogic1->RemoveFromLogic(0, 0, "&![7]");
fLogic1->RemoveFromLogic(0, 1, "&![7]");
fLogic1->RemoveFromLogic(0, 2, "&![7]");
}
//-----------------------------------------------------------------------------
void DTrigger::SwitchMTCAL(Int_t chan, Int_t inb, Int_t outb) {
// Turn a MT or CAL channel on or off. The arguments inb and outb refer
// to in-burst and out-of-burst. For example, SwitchMTCAL(3, 1, 0) would
// enable 3rd MT/CAL channel in burst and disable it out of burst.
char tbuf[80];
if (chan<2 || chan>7) return;
switch (10*(inb&1) + (outb&1)) {
case 00:
sprintf(tbuf,"0");
break;
case 01:
sprintf(tbuf,"[1]&[%d]",chan);
break;
case 10:
sprintf(tbuf,"[0]&[%d]",chan);
break;
case 11:
sprintf(tbuf,"([0]|[1])&[%d]",chan);
break;
default:
break;
}
fLogic1->DefineLogic(1, chan, tbuf);
}
//-----------------------------------------------------------------------------
void DTrigger::WriteFLTDownscal(Int_t tri,Int_t val) {
// Set downscaling factor for FLT channel tri to val.
fDown[FLT_DS[tri]]->WriteDownscale(FLT_Ch[tri],val);
}
//-----------------------------------------------------------------------------
Int_t DTrigger::GetFLTDownscal(Int_t tri) {
// Get downscaling factor for FLT channel tri.
return fDown[FLT_DS[tri]]->GetDownscale(FLT_Ch[tri]);
}
//-----------------------------------------------------------------------------
Int_t DTrigger::GetFLTCount(Int_t tri) {
// Get count of accepted FLT signals on channel tri.
return fDown[FLT_DS[tri]]->GetCounter(FLT_Ch[tri]);
}
//-----------------------------------------------------------------------------
void DTrigger::EnableFLT(Int_t tri) {
// Enable FLT channel tri.
fDown[FLT_DS[tri]]->EnableInOr(FLT_Ch[tri]);
fDown[FLT_DS[tri]]->Enable(FLT_Ch[tri]);
}
//-----------------------------------------------------------------------------
void DTrigger::DisableFLT(Int_t tri) {
// Disable FLT channel tri.
fDown[FLT_DS[tri]]->Disable(FLT_Ch[tri]);
fDown[FLT_DS[tri]]->DisableInOr(FLT_Ch[tri]);
}
//-----------------------------------------------------------------------------
void DTrigger::ManualFLTReset() {
// Reset FLT downscalers by software reset, and then generate Reset
// by flipping Busy.
// reset downscalers
fDown[0]->ResetDownscalers();
fDown[1]->ResetDownscalers();
fDown[2]->ResetDownscalers();
// flip busy
fBusyout->Norm(0);
fBusyout->Inv(0);
}
//-----------------------------------------------------------------------------
void DTrigger::ManualAbort() {
// Generate Abort by flipping the Abort line.
fAboout->Inv(0);
fAboout->Norm(0);
}
//-----------------------------------------------------------------------------
void DTrigger::EnableSDDMult(Int_t chan) {
// Enable Abort by SDD multiplicity
fDown2->EnableInOr(chan);
fDown2->Enable(chan);
}
//-----------------------------------------------------------------------------
void DTrigger::DisableSDDMult(Int_t chan) {
// Disable Abort by SDD multiplicity
fDown2->Disable(chan);
fDown2->DisableInOr(chan);
}
//-----------------------------------------------------------------------------
void DTrigger::WriteSDDMultThr(Int_t chan, Int_t thr) {
// Set SDD multiplicity threshold to thr. One unit is 4 mV.
fDisc->WriteThreshold(chan, thr);
}
//-----------------------------------------------------------------------------
void DTrigger::WriteSDDMultDownscal(Int_t chan, Int_t val) {
// Set SDD multiplicity downscaling factor.
fDown2->WriteDownscale(chan, val);
}
//-----------------------------------------------------------------------------
void DTrigger::EnableBusy(Int_t bus) {
// Enable busy bus in Busy-OR.
Int_t section = (bus>>2) & 0x1;
Int_t channel = (bus & 0x3);
fBusy[section]->Enable(channel);
}
//-----------------------------------------------------------------------------
void DTrigger::DisableBusy(Int_t bus) {
// Disable busy bus in Busy-OR.
Int_t section = (bus>>2) & 0x1;
Int_t channel = (bus & 0x3);
fBusy[section]->Disable(channel);
}
//-----------------------------------------------------------------------------
Int_t DTrigger::IsEnabledBBP() {
Int_t bbp0, bbp1, bbp2;
bbp0 = fLogic1->LogicContains(0, 0, "&![6]");
bbp1 = fLogic1->LogicContains(0, 1, "&![6]");
bbp2 = fLogic1->LogicContains(0, 2, "&![6]");
if (bbp0 & bbp1 & bbp2) return 1;
if (!bbp0 & !bbp1 & !bbp2) return 0;
cout << "DTrigger::IsEnableBBP shit: " << bbp0 << bbp1 << bbp2 << endl;
return 0;
}
//-----------------------------------------------------------------------------
Int_t DTrigger::IsEnabledIBP() {
Int_t bbp0, bbp1, bbp2;
bbp0 = fLogic1->LogicContains(0, 0, "&![7]");
bbp1 = fLogic1->LogicContains(0, 1, "&![7]");
bbp2 = fLogic1->LogicContains(0, 2, "&![7]");
if (bbp0 & bbp1 & bbp2) return 1;
if (!bbp0 & !bbp1 & !bbp2) return 0;
cout << "DTrigger::IsEnableBBP shit: " << bbp0 << bbp1 << bbp2 << endl;
return 0;
}
//-----------------------------------------------------------------------------
Int_t DTrigger::IsOnMTCAL(Int_t chan, Int_t burst) {
TString tbuf;
char inb[80];
char outb[80];
char none[80];
char both[80];
sprintf(inb, "[0]&[%1d]", chan);
sprintf(outb, "[1]&[%1d]", chan);
sprintf(none, "0");
sprintf(both, "([0]|[1])&[%1d]", chan);
sprintf(both, "[%1d]", chan);
fLogic1->ExtractLogic(1, chan, &tbuf);
if (tbuf.CompareTo(none) == 0) return 0;
if (tbuf.CompareTo(both) == 0) return 1;
if ((tbuf.CompareTo(inb) == 0) && burst) return 1;
if ((tbuf.CompareTo(outb) == 0) && !burst) return 1;
return 0;
}
//-----------------------------------------------------------------------------
Int_t DTrigger::IsEnabledFLT(Int_t tri) {
Int_t ena;
Int_t enainor;
ena = (fDown[FLT_DS[tri]]->GetEnableBit(FLT_Ch[tri]));
enainor = (fDown[FLT_DS[tri]]->GetEnableInOrBit(FLT_Ch[tri]));
if (ena == 0 && enainor == 0) return 0;
else if (ena != 0 && enainor != 0) return 1;
else {
cout << "Shit! enable and enable-in-or decoupled for FLT "
<< (int) tri << endl;
return 0;
}
}
//-----------------------------------------------------------------------------
Int_t DTrigger::IsEnabledAbort(Int_t abo) {
return fAboinp->IsEnabled(abo);
}
//-----------------------------------------------------------------------------
Int_t DTrigger::IsEnabledSDDMult(Int_t chan) {
Int_t ena;
Int_t enainor;
ena = fDown2->GetEnableBit(chan);
enainor = fDown2->GetEnableInOrBit(chan);
if (ena == 0 && enainor == 0) return 0;
if (ena && enainor) return 1;
cout << "Shit! enable and enable-in-or decoupled for SDD multiplicity" << endl;
return 0;
}
//-----------------------------------------------------------------------------
Int_t DTrigger::GetSDDMultThr(Int_t chan) {
return fDisc->GetThreshold(chan);
}
//-----------------------------------------------------------------------------
Int_t DTrigger::GetSDDMultDownscal(Int_t chan) {
return fDown2->GetDownscale(chan);
}
//-----------------------------------------------------------------------------
Int_t DTrigger::IsEnabledBusy(Int_t bus) {
Int_t section = (bus>>2) & 0x1;
Int_t channel = (bus & 0x3);
return fBusy[section]->IsEnabled(channel);
}
//-----------------------------------------------------------------------------
Int_t DTrigger::IsBusy(Int_t bus) {
Int_t section = (bus>>2) & 0x1;
Int_t channel = (bus & 0x3);
return fBusypat[section]->GetInput(channel);
}
//-----------------------------------------------------------------------------
void DTrigger::ReadVME() {
TObject *elem;
TIterator *iter;
iter = fModuleList->MakeIterator();
while ( (elem = iter->Next()) > 0) ((DModule*) elem)->ReadVME();
}
//*****************************************************************************
ROOT page - Class index - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.