// Author: Thomas Hadig (Group EB SLAC Stanford CA USA)
// Last update: $Date: 2003/08/27 19:51:12 $
// Copyright: Thomas Hadig, hadig@slac.stanford.edu
#ifndef __CRTTDC3377BOARD_CXX
#define __CRTTDC3377BOARD_CXX
////////////////////////////////////////////////////////////////////////////////
//
// Cosmic Ray Telescope Data Aquisition Software
//
// generic driver for Camac module: LeCroy 3377 TDC
//
// This module features:
// - 32 channels, 16 bits each
// - read-out is sequentially, i.e. 32 times reading of "channel" 0
// gives the 32 values
// - has seven control/test registers (encoded here as channel 1 to 8)
//
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <TSystem.h>
#include <gendriver/tdc3377board.hh>
#include <gendriver/camaccrate.hh>
namespace CRT
{
//{{{}}}
//{{{ default constructor
CrtTdc3377Board::CrtTdc3377Board() : CrtTdcAdcBoard()
{
// default constructor
fOk=0;
}
//}}}
//{{{ constructor CrtTdc3377Board(const Char_t *inName, Int_t inBoardNumber, CrtCamacCrate *inCrate)
CrtTdc3377Board::CrtTdc3377Board(const Char_t *inName, Int_t inBoardNumber, CrtCamacCrate *inCrate)
: CrtTdcAdcBoard(inName, inBoardNumber, inCrate)
{
// constructor
// inBoardNumber is the number of the Camac slot
// inCrate is a pointer to the Camac crate object
Int_t i=0;
while (i<7)
//{{{ fill identity array
{
fIdents[i]=inCrate->GetIdentity(inBoardNumber, i);
i++;
}
//}}}
fOk=1;
}
//}}}
//{{{ destructor
CrtTdc3377Board::~CrtTdc3377Board()
{
// destructor
}
//}}}
//{{{ Send
Int_t CrtTdc3377Board::Send(Int_t inCommand) const
{
// sends command to board
// available commands:
// CrtTdc3377Board::C_TDC3377_ClearModule
// CrtTdc3377Board::C_TDC3377_TestModule
if (fOk!=1) return -1;
switch (inCommand)
{
case C_TDC3377_ClearModule:
{
int ret = fInCrate->Send(fIdents[0], 9, 0);
usleep(200000); // wait > 200ms to module reset
return ret;
}
case C_TDC3377_TestModule:
return fInCrate->Send(fIdents[0], 25, 0);
}
return -1;
}
//}}}
//{{{ Enable
Int_t CrtTdc3377Board::Enable(Int_t inFlag, Int_t) const
{
// enables board features
// Available features:
// CrtTdc3377Board::F_TDC3377_LAM (Look-At-Me)
// CrtTdc3377Board::F_TDC3377_ACQUISITION
if (fOk!=1) return -1;
switch(inFlag)
{
case F_TDC3377_LAM:
return fInCrate->Send(fIdents[0], 26, 0);
case F_TDC3377_ACQUISITION:
return fInCrate->Send(fIdents[1], 26, 0);
}
return -1;
}
//}}}
//{{{ Disable
Int_t CrtTdc3377Board::Disable(Int_t inFlag, Int_t) const
{
// disables board features
// Available features:
// CrtTdc3377Board::F_TDC3377_LAM (Look-At-Me)
// CrtTdc3377Board::F_TDC3377_ACQUISITION
if (fOk!=1) return -1;
switch(inFlag)
{
case F_TDC3377_LAM:
return fInCrate->Send(fIdents[0], 24, 0);
case F_TDC3377_ACQUISITION:
return fInCrate->Send(fIdents[1], 24, 0);
}
return -1;
}
//}}}
//{{{ Clear
Int_t CrtTdc3377Board::Clear(Int_t inFlag, Int_t) const
{
// clears board features
// Available features:
// CrtTdc3377Board::F_TDC3377_LAM (Look-At-Me)
if (fOk!=1) return -1;
switch(inFlag)
{
case F_TDC3377_LAM:
return fInCrate->Send(fIdents[0], 10, 0);
}
return -1;
}
//}}}
//{{{ Test
Int_t CrtTdc3377Board::Test(Int_t inFlag, Int_t) const
{
// tests board features
// Available features:
// CrtTdc3377Board::F_TDC3377_LAM (Look-At-Me)
// CrtTdc3377Board::F_TDC3377_BufferingInProgress
// CrtTdc3377Board::F_TDC3377_BUSY
// CrtTdc3377Board::F_TDC3377_EVENT_RDY
// CrtTdc3377Board::F_TDC3377_FIFO_TAG
if (fOk!=1) return -1;
switch(inFlag)
{
case F_TDC3377_LAM:
return fInCrate->Test(fIdents[0], 8);
case F_TDC3377_BufferingInProgress:
return fInCrate->Test(fIdents[0], 27);
case F_TDC3377_BUSY:
return fInCrate->Test(fIdents[1], 27);
case F_TDC3377_EVENT_RDY:
return fInCrate->Test(fIdents[2], 27);
case F_TDC3377_FIFO_TAG:
return fInCrate->Test(fIdents[3], 27);
}
return -1;
}
//}}}
//{{{ Query
Int_t CrtTdc3377Board::Query(Int_t inChannel, Int_t *outValue) const
{
// queries channels
// available channels:
// 0: sequentially read data of all 32 channels
// return value encodes the value and the channel number
// 1: control register 0
// 2: control register 1
// 3: control register 2
// 4: control register 3
// 5: control register 4
// 6: control register 5
// 7: CAMAC test register
if (fOk!=1) return -1;
if (inChannel==0)
return fInCrate->Read(fIdents[0], 0, outValue);
if ((inChannel<1)||(inChannel>7)) return -1;
return fInCrate->Read(fIdents[inChannel-1], 1, outValue);
}
//}}}
//{{{ Assign
Int_t CrtTdc3377Board::Assign(Int_t inChannel, Int_t inValue) const
{
// assigns channels
// available channels:
// 0: FIFO
// 1: control register 0
// 2: control register 1
// 3: control register 2
// 4: control register 3
// 5: control register 4
// 6: control register 5
// 7: FIFO tag bit
if (fOk!=1) return -1;
if (inChannel==0)
return fInCrate->Send(fIdents[0], 16, inValue);
if (inChannel==7)
return fInCrate->Send(fIdents[1], 16, inValue);
if ((inChannel<1)||(inChannel>6)) return -1;
return fInCrate->Send(fIdents[inChannel-1], 17, inValue);
}
//}}}
//{{{ Initialize
Int_t CrtTdc3377Board::Initialize() const
{
// initializes the board
Send(C_TDC3377_ClearModule);
fInCrate->Send(fIdents[0], 30, 0); // start programming
# ifdef __CRTTDC3377_SINGLE_WORD
fInCrate->Send(fIdents[0], 21, 0); // select common start, single word
# else
fInCrate->Send(fIdents[0], 23, 0); // select common start, double word
# endif
fInCrate->Send(fIdents[0], 25, 0); // load the program
usleep(200000); // wait > 200ms to let the module to the programming
while (fInCrate->Test(fIdents[0], 13)==0); // wait for successfull Xilinx test
Send(C_TDC3377_ClearModule);
//Assign(1, 0x1000); // Multi-event buffers
# ifdef __CRTTDC3377_NO_HEADER_WORD
Assign(1, 0x2000); // no Multi-event buffers, no header word, leading edge only
# else
Assign(1, 0); // no Multi-event buffers, with header word, leading edge only
# endif
Assign(2, 0); // no MPI
Assign(3, 0); // allow 16 hits per TDC
# ifdef __CRTTDC3377_SINGLE_WORD
Assign(4, 0x0280); // no FERA, 320ns time out
# else
Assign(4, 0); // no FERA
# endif
Assign(5, 0x0007); // 350nano-sec time out
Assign(6, 0); // no test mode
return 1;
}
//}}}
//{{{ Prepare
Int_t CrtTdc3377Board::Prepare() const
{
// prepares the board for data taking
Clear(F_TDC3377_LAM); // clear LAMs
Enable(F_TDC3377_LAM); // enable LAMs
fInCrate->Send(fIdents[1], 26, 0); // anable data aquisition
return 1;
}
//}}}
//{{{ HasData
Int_t CrtTdc3377Board::HasData() const
{
// tests whether the module has data available
return Test(F_TDC3377_LAM);
}
//}}}
//{{{ ReadModule
Int_t CrtTdc3377Board::ReadModuleAndClear(Int_t *outChannels) const
{
// reads all channels and clears the data afterwards.
// returns only first reported hit in each channel.
// This is actually the one with the highest time value.
# ifdef __CRTTDC3377_DEBUG
// for debugging purposes
static int datastore[4000];
static int fifo[4000];
int datastorecounter=0;
# endif
memset(outChannels,0,32*sizeof(Int_t));
if (fOk!=1) return -1;
# if 0
if (Test(CrtTdc3377Board::F_TDC3377_BUSY)==0)
//{{{ return, no data
{
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return 0;
}
//}}}
# endif
if (Test(CrtTdc3377Board::F_TDC3377_FIFO_TAG)==1)
//{{{ return, no data
{
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return 0;
}
//}}}
Int_t value;
if (Query(0,&value)==0)
//{{{ return, no data
{
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return 0;
}
//}}}
Int_t count=0;
while (Test(CrtTdc3377Board::F_TDC3377_FIFO_TAG)!=1)
//{{{ forever
{
if (Query(0,&value)==0)
//{{{ handle no data case
{
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return count;
}
//}}}
# ifdef __CRTTDC3377_DEBUG
if (datastorecounter<4000)
//{{{ store all data
{
datastore[datastorecounter]=value;
fifo[datastorecounter]= Test(CrtTdc3377Board::F_TDC3377_FIFO_TAG);
datastorecounter++;
}
//}}}
# endif
Int_t data, channel;
# ifdef __CRTTDC3377_SINGLE_WORD
//{{{ single word
if (value < 0) // should be & 0x8000 !=0 but value is signed !
//{{{ error
{
std::cout <<"Error in reading ... data word for single numbers no data word !"<<std::endl;
# ifdef __CRTTDC3377_DEBUG
std::cout <<"Dumping all data ("<<datastorecounter<<" words)"<<std::endl;
Int_t i=0;
while (i<datastorecounter)
{
std::cout<<i<<" "<<hex<<datastore[i]<<" fifo = "<<fifo[i]<<std::endl;
i++;
}
std::cout<<dec<<std::endl;
# endif
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return 0;
}
//}}}
data = (value & 0x03FF);
channel = (value & 0x7C00) >>10;
//}}}
# else
//{{{ double word
// data structure is 2*8 bit data, 1 bit edge polarity, 5 bit channel
// first word of double word
data = (value & 0xFF) << 8;
channel = (value & 0x7C00) >>10;
if (Query(0,&value)==0)
//{{{ handle no data case
{
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return count;
}
//}}}
# ifdef __CRTTDC3377_DEBUG
if (datastorecounter<4000)
//{{{ store all data
{
datastore[datastorecounter]=value;
fifo[datastorecounter]= Test(CrtTdc3377Board::F_TDC3377_FIFO_TAG);
datastorecounter++;
}
//}}}
# endif
// second word of double word
data += (value & 0xFF);
if (channel != ((value & 0x7C00)>>10))
//{{{ error
{
std::cout <<"Error in reading ... channel numbers do not agree !"<<std::endl;
# ifdef __CRTTDC3377_DEBUG
std::cout <<"Dumping all data ("<<datastorecounter<<" words)"<<std::endl;
Int_t i=0;
while (i<datastorecounter)
{
std::cout<<i<<" "<<hex<<datastore[i]<<" fifo = "<<fifo[i]<<std::endl;
i++;
}
std::cout<<dec<<std::endl;
# endif
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return 0;
}
//}}}
//}}}
# endif
if (outChannels[channel]<1)
//{{{ store data
{
outChannels[channel]=data;
count++;
}
//}}}
}
//}}}
Query(0,&value);
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return count;
}
//}}}
//{{{ ReadModule (with limits)
Int_t CrtTdc3377Board::ReadModuleAndClear(Int_t *outChannels, Int_t inLowerLimit, Int_t inUpperLimit) const
{
// reads all channels and clears the data afterwards.
// returns at most one hit in each channel.
// In case there are no hits inside the limits, reports the earliest hit
// In case there are hits inside the limits, reports the earliest of the hits inside the limits
if (inLowerLimit<=0) inLowerLimit=1; // to protect us from counting wrong
# ifdef __CRTTDC3377_DEBUG
// for debugging purposes
static int datastore[4000];
static int fifo[4000];
int datastorecounter=0;
# endif
memset(outChannels,0,32*sizeof(Int_t));
if (fOk!=1) return -1;
# if 0
if (Test(CrtTdc3377Board::F_TDC3377_BUSY)==0)
//{{{ return, no data
{
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return 0;
}
//}}}
# endif
if (Test(CrtTdc3377Board::F_TDC3377_FIFO_TAG)==1)
//{{{ return, no data
{
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return 0;
}
//}}}
Int_t value;
if (Query(0,&value)==0)
//{{{ return, no data
{
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return 0;
}
//}}}
Int_t count=0;
while (Test(CrtTdc3377Board::F_TDC3377_FIFO_TAG)!=1)
//{{{ forever
{
if (Query(0,&value)==0)
//{{{ handle no data case
{
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return count;
}
//}}}
# ifdef __CRTTDC3377_DEBUG
if (datastorecounter<4000)
//{{{ store all data
{
datastore[datastorecounter]=value;
fifo[datastorecounter]= Test(CrtTdc3377Board::F_TDC3377_FIFO_TAG);
datastorecounter++;
}
//}}}
# endif
Int_t data, channel;
# ifdef __CRTTDC3377_SINGLE_WORD
//{{{ single word
if (value < 0) // should be & 0x8000 !=0 but value is signed !
//{{{ error
{
std::cout <<"Error in reading ... data word for single numbers no data word !"<<std::endl;
# ifdef __CRTTDC3377_DEBUG
std::cout <<"Dumping all data ("<<datastorecounter<<" words)"<<std::endl;
Int_t i=0;
while (i<datastorecounter)
{
std::cout<<i<<" "<<hex<<datastore[i]<<" fifo = "<<fifo[i]<<std::endl;
i++;
}
std::cout<<dec<<std::endl;
# endif
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return 0;
}
//}}}
data = (value & 0x03FF);
channel = (value & 0x7C00) >>10;
//}}}
# else
//{{{ double word
// data structure is 2*8 bit data, 1 bit edge polarity, 5 bit channel
// first word of double word
data = (value & 0xFF) << 8;
channel = (value & 0x7C00) >>10;
if (Query(0,&value)==0)
//{{{ handle no data case
{
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return count;
}
//}}}
# ifdef __CRTTDC3377_DEBUG
if (datastorecounter<4000)
//{{{ store all data
{
datastore[datastorecounter]=value;
fifo[datastorecounter]= Test(CrtTdc3377Board::F_TDC3377_FIFO_TAG);
datastorecounter++;
}
//}}}
# endif
// second word of double word
data += (value & 0xFF);
if (channel != ((value & 0x7C00)>>10))
//{{{ error
{
std::cout <<"Error in reading ... channel numbers do not agree !"<<std::endl;
# ifdef __CRTTDC3377_DEBUG
std::cout <<"Dumping all data ("<<datastorecounter<<" words)"<<std::endl;
Int_t i=0;
while (i<datastorecounter)
{
std::cout<<i<<" "<<hex<<datastore[i]<<" fifo = "<<fifo[i]<<std::endl;
i++;
}
std::cout<<dec<<std::endl;
# endif
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return 0;
}
//}}}
//}}}
# endif
if ((outChannels[channel]>=inLowerLimit)&&(outChannels[channel]<=inUpperLimit))
//{{{ we already have a hit inside the limits, use the lower one
{
if ((data<outChannels[channel])&&(data>=inLowerLimit))
//{{{ store data
{
outChannels[channel]=data;
}
//}}}
}
//}}}
else if ((outChannels[channel]==0)&&(data>0))
//{{{ we do not yet have a hit
{
outChannels[channel]=data;
count++;
}
//}}}
else if (data<outChannels[channel])
//{{{ we have a hit outside the limits, then store the earlier one
{
outChannels[channel]=data;
}
//}}}
}
//}}}
Query(0,&value);
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return count;
}
//}}}
//{{{ ReadModuleAllHits
Int_t CrtTdc3377Board::ReadModuleAllHitsAndClear(Int_t *outChannels) const
{
// reads all hits on all channels and clears the data afterwards.
// The array given has to have the size
// MAX_HITS * MAX_CHANNELS = 16 * 32 = 512,
// the data will be ordered: hit_in_channel * 32 + channel_no
Int_t i=0, value;
Int_t currentnum[32];
while (i<32*16)
{
outChannels[i++]=0;
}
i=0;
while (i<32)
{
currentnum[i++]=0;
}
if (Test(CrtTdc3377Board::F_TDC3377_FIFO_TAG)==1)
//{{{ return, no data
{
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return 0;
}
//}}}
if (Query(0,&value)==0)
//{{{ return, no data
{
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return 0;
}
//}}}
Int_t count=0;
while (Test(CrtTdc3377Board::F_TDC3377_FIFO_TAG)!=1)
//{{{ forever
{
if (Query(0,&value)==0)
//{{{ handle no data case
{
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return count;
}
//}}}
# ifdef __CRTTDC3377_DEBUG
if (datastorecounter<4000)
//{{{ store all data
{
datastore[datastorecounter]=value;
fifo[datastorecounter]= Test(CrtTdc3377Board::F_TDC3377_FIFO_TAG);
datastorecounter++;
}
//}}}
# endif
Int_t data, channel;
# ifdef __CRTTDC3377_SINGLE_WORD
//{{{ single word
if (value < 0) // should be & 0x8000 !=0 but value is signed !
//{{{ error
{
std::cout <<"Error in reading ... data word for single numbers no data word !"<<std::endl;
# ifdef __CRTTDC3377_DEBUG
std::cout <<"Dumping all data ("<<datastorecounter<<" words)"<<std::endl;
Int_t i=0;
while (i<datastorecounter)
{
std::cout<<i<<" "<<hex<<datastore[i]<<" fifo = "<<fifo[i]<<std::endl;
i++;
}
std::cout<<dec<<std::endl;
# endif
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return 0;
}
//}}}
data = (value & 0x03FF);
channel = (value & 0x7C00) >>10;
//}}}
# else
//{{{ double work
// data structure is 2*8 bit data, 1 bit edge polarity, 5 bit channel
// first word of double word
data = (value & 0xFF) << 8;
channel = (value & 0x7C00) >>10;
if (Query(0,&value)==0)
//{{{ handle no data case
{
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return count;
}
//}}}
# ifdef __CRTTDC3377_DEBUG
if (datastorecounter<4000)
//{{{ store all data
{
datastore[datastorecounter]=value;
fifo[datastorecounter]= Test(CrtTdc3377Board::F_TDC3377_FIFO_TAG);
datastorecounter++;
}
//}}}
# endif
// second word of double word
data += (value & 0xFF);
if (channel != ((value & 0x7C00)>>10))
//{{{ error
{
std::cout <<"Error in reading ... channel numbers do not agree !"<<std::endl;
# ifdef __CRTTDC3377_DEBUG
std::cout <<"Dumping all data ("<<datastorecounter<<" words)"<<std::endl;
Int_t i=0;
while (i<datastorecounter)
{
std::cout<<i<<" "<<hex<<datastore[i]<<" fifo = "<<fifo[i]<<std::endl;
i++;
}
std::cout<<dec<<std::endl;
# endif
Clear(CrtTdc3377Board::F_TDC3377_LAM);
return 0;
}
//}}}
//}}}
# endif
if (currentnum[channel]<16)
//{{{ store data
{
// if (currentnum[channel]>0)
// if (outChannels[(currentnum[channel]-1)*32+channel]==data)
// continue; // suppress multiple hits at same time
outChannels[currentnum[channel]*32+channel]=data;
currentnum[channel]++;
count++;
}
//}}}
}
//}}}
return count;
}
//}}}
//{{{ GetNumberOfChannels
Int_t CrtTdc3377Board::GetNumberOfChannels() const
{
return 32;
}
//}}}
}
ClassImp(CRT::CrtTdc3377Board) //LeCroy 3377 TDC module driver
#endif
ROOT page - Class index - Class Hierarchy - 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.