//Author: Dariusz Mi$kowiec
//Date:   1999

///////////////////////////////////////////////////////////////////////////////
// DLogic handles the VME dual logic unit V495 (CAEN). This unit can work as
// a logic unit, input/output register, or pattern generator. 
///////////////////////////////////////////////////////////////////////////////

#include "DLogic.h"

#ifdef COMPIL 
  ClassImp(DLogic)
#endif

//*****************************************************************************
 DLogic::DLogic(Char_t *mdesc, UInt_t addr) : 
       DModule("logic unit","CAEN V495",mdesc,addr) {
  cout<<"constructing DLogicn";
}
//-----------------------------------------------------------------------------
 DLogic::~DLogic() {
  cout<<"destroying DLogicn";
}
//-----------------------------------------------------------------------------
 void DLogic::WriteAddrReg(Int_t sec, Int_t addr) {
  Access("w", 0x600 + (sec&1)*0x200 + (UChar_t) addr*2, 2, &fDummy);
}
//-----------------------------------------------------------------------------
 void DLogic::WriteRAM(Int_t sec, UShort_t *buf) { 
  // basic RAM-writing method

  UShort_t regist;
  ReadVME();
  regist = GetConfReg();
  EditMode(sec);
  Access("w", 0x200 + (sec&1)*0x200, 512, buf);
  ReadRAM();
  WriteConfReg(regist);
}
//-----------------------------------------------------------------------------
 void DLogic::WriteRAM(Int_t sec, UShort_t dat) { 
  // write same number dat into all RAM locations
  UShort_t buf[256];
  int i;
  for (i=0; i<256; i++) {
    buf[i] = dat;
  }
  WriteRAM(sec, buf);
}
//-----------------------------------------------------------------------------
 void DLogic::WriteRAM(Int_t sec, Char_t* flag) { 
  // Write a predefined sequence into RAM. 

  UShort_t buf[256];
  Int_t i;

  // diagonal matrix

  if (strcmp(flag,"i")==0) {
    for (i=0; i<256; i++) {
      buf[i] = (UShort_t) i;
    }
  WriteRAM(sec, buf);
  }
}
//-----------------------------------------------------------------------------
 void DLogic::ReadVME() {

  UChar_t buf[256];

  Access("r", 0x004,   2, &fOutputReg);
  Access("r", 0x006,   2, &fInputReg);
  Access("r", 0x002,   2, &fConfReg);
  Access("r", 0x0fa,   6, &buf[0xfa]);
  memcpy(&fFixCodeF5, &buf[0xfa],1);
  memcpy(&fFixCodeFA, &buf[0xfb],1);

  fManufacturer = buf[0xfd]>>2;
  fModType = (buf[0xfd] & 0x3) * 0x100 + buf[0xfc];
  fVersion      = buf[0xff]>>4;
  fSerial       = (buf[0xff] & 0xf) * 0x100 + buf[0xfe];
}
//-----------------------------------------------------------------------------
 void DLogic::ReadRAM() {
  // Basic RAM-reading method. It is separated from ReadVME because it
  // affects the operation of the unit and should not be done unless
  // really needed. 

  UShort_t regist;
  UShort_t tempbuf[256];

  ReadVME();
  regist = GetConfReg();
  EditMode(0);
  EditMode(1);
  Access("r", 0x200, 512, fARAM);
  Access("r", 0x400, 512, tempbuf);

  // I do not understand why but I need to swap bytes for section B

  swab(tempbuf,fBRAM,512);
  WriteConfReg(regist);
}
//-----------------------------------------------------------------------------
 void DLogic::ResetModule() {
  WriteConfReg(0x0);
  WriteRAM(0, (UShort_t) 3); 
  WriteRAM(0, (UShort_t) 7); 
}
//-----------------------------------------------------------------------------
 void DLogic::LogicMode(Int_t sec) { 
  DisableStrobe(sec);
  StopPatGen(sec);
  SelectExtInput(sec);
  SelectRAMOutput(sec);
}
//-----------------------------------------------------------------------------
 void DLogic::PatternMode(Int_t sec) {
  DisableStrobe(sec);
  SelectVMEInput(sec);
  SelectRAMOutput(sec);
  StartPatGen(0);
}
//-----------------------------------------------------------------------------
 void DLogic::IORegisterMode(Int_t sec) {
  DisableStrobe(sec);
  StopPatGen(sec);
  SelectExtInput(sec);
  SelectVMEOutput(sec);
}
//-----------------------------------------------------------------------------
 void DLogic::EditMode(Int_t sec) {
  DisableStrobe(sec);
  StopPatGen(sec);
  SelectVMEInput(sec);
  SelectRAMOutput(sec);
}
//-----------------------------------------------------------------------------
 void DLogic::DumpConfReg() {
  int i;
  for (i=0; i<=10; i++) {
    printf("%2d  ",i);
    printf("%1dn", (fConfReg>>i)&1);
  }
}
//-----------------------------------------------------------------------------
 void DLogic::DumpARAM() {
  int i,j;
  printf("n");
  for (i=0; i<16; i++) {
    printf("%3d:    ", 16*i);
    for (j=0; j<16; j++) {
      printf("%2x  ", fARAM[16*i+j] & 0xff);
    }
    printf("n");
  }
}
//-----------------------------------------------------------------------------
 void DLogic::DumpBRAM() {
  int i,j;
  printf("n");
  for (i=0; i<16; i++) {
    printf("%3d:    ", 16*i);
    for (j=0; j<16; j++) {
      printf("%2x  ", fBRAM[16*i+j] & 0xff);
    }
    printf("n");
  }
}
//-----------------------------------------------------------------------------
 void DLogic::ExtractLogic(Int_t sec, Int_t outchan, TString *tbuf) {
  // Scan the data matrix and try to figure out the logic underlying the 
  // outchan-th output bit.  The routine is intelligent enough to recognize 
  // coincidences and anticoincidences. The result will be stored in 
  // tbuf in the format like [0]&^[1]. 

  // or[i] (and[i]) contains an OR (AND) of all such input bit configurations 
  // that the i-th output bit is 1. 

  Int_t j;
  UShort_t on,off;
  Char_t temp[80];
  UShort_t *fData;
  Int_t always0;
  Int_t always1;

  on = 0xff;
  off = 0xff;
  always0 = 1;
  always1 = 1;

  if (sec == 0) fData = fARAM;
  else if (sec == 1) fData = fBRAM;
  else {
    cout << "DLogic::ExtractLogic: What?n";
    return;
  }
  
  // scan the input bit configurations, determine or[outchan] and and[outchan]

  for (j=0; j<256; j++) {
    if (fData[j]>>outchan & 1) {
      always0 = 0;
      on = on & j;
      off = off & (0xff^j);
    } else {
      always1 = 0;
    }
  }

  // extract logic from or, and, always0, and always1

  tbuf->Remove(0);

  if (always0) {
    sprintf(temp,"0");
    tbuf->Append(temp);
  }

  if (always1) {
    sprintf(temp,"1");
    tbuf->Append(temp);
  }

  if ((on & off) == 0 && (on | off) != 0) {   // reasonable combination
    for (j=0; j<8; j++) {
      if (on>>j & 1) {
	sprintf(temp,"[%1d]&",j);
	tbuf->Append(temp);
      }
      if (off>>j & 1) {
	sprintf(temp,"![%1d]&",j);
	tbuf->Append(temp);
      }
    }

  // some cosmetics

  if (tbuf->Length()>0) 
    tbuf->Remove(tbuf->Length()-1,1);

  }

    //  cout << outchan << "on=" << on << "off=" << off << endl;

}
//-----------------------------------------------------------------------------
 void DLogic::DefineLogic(Int_t sec, Int_t outchan, char *definition) {
  // Redefine the i-th bit of the array fData cells to be equal to 
  // definition, where definition represents a logic function of
  // the input bits. 
  // outchan - which output bit (0-7)
  // definition - logic expression, like "([0] & [1]) | [7]"

  TFormula *outdef;
  Int_t j,k;
  UShort_t usbuf[256];

  memcpy(usbuf, GetRAM(sec), 512);
  outdef = new TFormula("outdef",definition);

  for (j=0; j<256; j++) {
    for (k=0; k<8; k++) {
      outdef->SetParameter(k, (j>>k) & 0x1);
    }
    setbit(&usbuf[j], outchan, (Int_t) (outdef->Eval(0)) & 0x1);
  }

  delete outdef;

  WriteRAM(sec, usbuf);
}
//-----------------------------------------------------------------------------
 void DLogic::AddToLogic(Int_t sec, Int_t outchan, char *definition) {
  // Append string definition to the current logic definition of chan outchan.

  TString tbuf;
  ExtractLogic(sec, outchan, &tbuf);
  if (tbuf.Length() == 0) {
    cout << "DLogic::AddToLogic: attempt to add " << definition << "to empty definition" << endl;
    return;
  }
  tbuf.Append(definition);
  DefineLogic(sec, outchan, (char *) tbuf.Data());
}
//-----------------------------------------------------------------------------
 Int_t DLogic::LogicContains(Int_t sec, Int_t outchan, char *definition) {
  // Check if logic definition of channel outchan contains string definition.
  TString tbuf;
  ExtractLogic(sec, outchan, &tbuf);
  return tbuf.Contains(definition);
}
//-----------------------------------------------------------------------------
 void DLogic::RemoveFromLogic(Int_t sec, Int_t outchan, char *definition) {
  // Remove string definition from current logic definition of channel outchan.
  TString tbuf;
  ExtractLogic(sec, outchan, &tbuf);
  if (tbuf.Contains(definition)) {
    tbuf.ReplaceAll(definition,"");
    DefineLogic(sec, outchan, (char *) tbuf.Data());
  } else {
    cout << "DLogic::RemoveFromLogic warning: attempt to remove " << definition << "from " << tbuf.Data() << endl;
  }
}
//*****************************************************************************


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.