DAQMB and CFEB Software
S.
Durkin, J. Gu
March
18, 2002
Overview of Low Level Routines
All
slow control commands are handled through the libraries located in
fast_daq/drivers/jtag-5.0.
To call these routines one first specifies
the
type of board and VME slot number one is talking to. Subroutines are
then
called, and at completion one calls an end routine.
start_osu(vmeslot);
start_rice(vmeslot);
start_ucla(vmeslot)
... ... ...
routines routines routines
... ... ...
end_osu(); end_rice(); end_ucla();
Here
vmeslot is an integer between 2 and 21. Putting in vmeslot=25 means broadcast
to all DAQMB's, 26 to all TMB’s, and 27 to all DAMB’s and TMB’s.
The osu
routines are all using a routine called devdo.
devdo(dev,ncmd,cmd,nbuf,sndbuf,rcvbuf,icntrl)
dev - device
ncmd - number of command bits to
send
cmd - command bits
nbuf - number of data bits to
send
sndbuf - data bits
rcvbuf - returned data bits
icntrl - control flag
0 buffer command, don't
send to d360
1 send all buffered
commands to d360
2 a readback is
required,send all buffered
commands to d360
The
following devices are supported in devdo:
F1PROM - CFEB 1 PROM
F2PROM - CFEB 2 PROM
F3PROM - CFEB 3 PROM
F4PROM - CFEB 4 PROM
F5PROM - CFEB 5 PROM
FAPROM - CFEB ALL PROMs
F1SCAM - CFEB 1 Control FPGA
F2SCAM - CFEB 2 Control FPGA
F3SCAM - CFEB 3 Control FPGA
F4SCAM - CFEB 4 Control FPGA
F5SCAM - CFEB 5 Control FPGA
FASCAM - CFEB ALL Control FPGAs
MCTRL- DAQMB control FPGA
MPROM - DAQMB control PROM
VPROM - DAQMB MVE PROM
CDAC - Trigger Comparator DAC
MADC - ADC's
FIFO1 - CFEB 1 FIFO
FIFO2 - CFEB 2 FIFO
FIFO3 - CFEB 3 FIFO
FIFO4 - CFEB 4 FIFO
FIFO5 - CFEB 5 FIFO
FIFO6 - CFEB Overlap FIFO
FIFO7 - TriggerMB FIFO
LOWVOLT - Davis Low Voltage Board
STATUS - Not implimented
RESET - Emergency programming of VME FPGA
We have
provided a program cfeb_control which performs almost
all
slow control commands. Below is an explaination of these
commands.
Configure
->Setup(setup_cb)
->
Full Setup
->
Program All(BCKPLN)
->
Resets All(BKPLN)
->
Reset ALL(MB)
-> Init Buckeye's
Full Setup
The
final version of the DAQMB will remove any setup requirements. For
now
though a set of commands is necessary to initialize the program.
The
call sequence is as follows:
1. setcaldelay(dp->cal_delay,dp);
set_dav_delay(dp->dav_delay);
fxpreblkend(ALL,dp->pre_blk_end,dp);
2. calctrl_fifomrst();
3. set_comp_mode(ALL,dp->comp_mode,dp);
set_comp_thresh(ALL,dp->set_comp_thresh,dp);
4. preamp_initx(ALL,dp);
5. ddu_reset();
Step 1
initializes the delay settings on the board. Step 2 clears the
FIFOs
on the DAQMB. Step 3 initializes the CERN comparator chip, and
Step 4
shifts the buckeye chips into normal mode. Step 5 resets the
gigabit
ethernet driver. These routines will be discussed later.
Program All(BCKPLN)
Tells
the CCB to send a reprogram signal on the backplane which reloads
all
FPGA's from their EPROMs. Note: this clearly wipes out the constants
loaded
in Full Setup.
prgall_bckpln(dp);
Reset All (BCKPLN)
Tell
the CCB to send a reset signal on the backplane which resets all
FPGA's.
reset_bckpln(dp);
Reset ALL(MB)
Same as
the previous reset command but done locally through the DAQMB FPGA.
calctrl_global();
Init Buckeye's
The
buckeyes have a 48 bit shift register which sets pulsing modes
on the
buckeye. This routine sets all channels to normal mode.
preamp_initx(ALL,dp);
Configure
-> Load Proms
-> Load/Prg. FEB's(prg_feb_cb)
FEB1: prgm SCAM
FEB1: load ISPROM
FEB2: prgm SCAM
FEB2: load ISPROM
FEB3: prgm SCAM
FEB3: load ISPROM
FEB4: prgm SCAM
FEB4: load ISPROM
FEB5: prgm SCAM
FEB5: load ISPROM
-> Load/Prg. MB (prg_mthrbrd_cb)
load VME ISPROM(emergency)
load VME ISPROM
prgm VME VTX
load CNTRL ISPROM
prgm CNTRL VTX
Each
FEB has a single control FPGA loaded by a single prom. The DAQMB has
a VME
prom, a VME FPGA, a control prom, and a control FPGA.
FEB1: prgm SCAM
The FEB
PROM firmware is loaded into the CFEB FPGA.
cfeb_vtx_prom(F1PROM,dp);
FEB1: load ISPROM
Loads
Firmware from disk into CFEB EPROM.
cbrdnum=(char *)malloc(5);
febpromuser2(dp->devnum,dp,cbrdnum);
printf(" download svf file n");
epromload(dp->s[0],dp->devnum,buf,1,cbrdnum);
printf(" file has been downloaded \n");
free(cbrdnum);
The
routine febpromuser2 reads the board number from the FPGA.
epromload
then loads the eprom writing the board number into
its
firmware in the process.
load VME ISPROM(emergency)
Loads
Firmware from disk into DAQMB VME PROM. Slow but necessary
if FPGA
looses firmware.
cbrdnum=(char *)malloc(8);
printf(" download svf file n");
epromload(RESET,dp->devnum,buf,1,cbrdnum);
printf(" file has been downloaded \n");
free(cbrdnum);
load VME ISPROM
Loads
Firmware from disk into DAQMB VME PROM. Same program as above.
cbrdnum=(char *)malloc(8);
printf(" download svf file n");
epromload(VPROM,dp->devnum,buf,1,cbrdnum);
printf(" file has been downloaded \n");
free(cbrdnum);
prgm VME VTX
Not
implimented. Use global Program All (BCKPLN) above.
load CNTRL ISPROM
Loads
Firmware from disk into DAQMB Control PROM.
cbrdnum=(char *)malloc(8);
printf(" download svf file n");
epromload(MPROM,dp->devnum,buf,1,cbrdnum);
printf(" file has been downloaded \n");
free(cbrdnum);
prgm CNTRL VTX
Not
implimented. Use global Program All (BCKPLN) above.
Configure
-> Resets(resets_cb)
-> Reset DDU
-> Reset FIFO
Reset DDU
Clears
memory area in Gigabit ethernet driver.
ddu_reset();
Reset FIFO
Clears
DAQMB fifo's.
calctrl_fifomrst();
Configure
->Load Constants(lc_cb)
->Load DAQMB Crate ID
->Calibration Delay
->FEB Delays
->Trig. DAV Delays
->Calib. DAC
->Set Comparator Threshold
->Set Comparator Mode
->Set Pre-BlockEnd
->Init Buckeye's
->Set R_trg Rate"
Load DAQMB Crate ID
Load a
crate ID for data header.
setcrateid(dly);
Calibration Delay
setcaldelay(dly,dp);
FEB Delays
setfebdelay(dly);
Trig. DAV Delays
set_dav_delay(dly);
Calib. DAC
Set the
voltage on the precision pulse capacitors and trigger pulse capacitors.
set_dac(volt1,volt2,dp);
Set Comparator Threshold
Set the
threshold for the comparator chip.
set_comp_thresh(ALL,thresh,dp);
Set Comparator Mode
Set the
mode on the comparator chip.
set_comp_mode(dp->devnum,cmode,dp);
Set Pre-BlockEnd
fxpreblkend(dp->devnum,pbe,dp);
Init Buckeye's
Shift
buckeyes into normal mode.
preamp_initx(ALL,dp);
Set R_trg Rate
set_trg_rate(dly,dp);
Stats
-> Status(status_cb)
Not
implimented yet.
Stats
-> Temps(temp_cb)
-> ALL temp
-> DMB Temp
-> CFEB1 Temp
-> CFEB2 Temp
-> CFEB3 Temp
-> CFEB4 Temp
-> CFEB5 Temp
-> Virtex Junct. Temp
-> Hist Temps (2 minutes)
ALL temp
There
are thermistors on each CFEB and one on the DAQMB. These
commands
read the temperatures.
readthermx(0);
printf("Reading FEB1 temperature\n");
readthermx(1);
printf("Reading FEB2 temperature\n");
readthermx(2);
printf("Reading FEB3 temperature\n");
readthermx(3);
printf("Reading FEB4 temperature\n");
readthermx(4);
printf("Reading FEB5 temperature\n");
readthermx(5);
printf("Reading Virtex temperature\n");
readthermx(7);
Note:
Virtex junction temperature presently has no meaning
Stats
->Comp Volts (compv_cb)
-> ALL Comp DAC
-> Comp DAC1
-> Comp DAC2
-> Comp DAC3
-> Comp DAC4
-> Comp DAC5
-> Hist Comp
All Comp DAC
Readback
of the comparator chip threshold.
printf("Reading all Comp. DACs\n");
printf("Reading DAC1 Volts\n");
adcplus(2,0);
printf("Reading DAC2 Volts\n");
adcplus(2,1);
printf("Reading DAC3 Volts\n");
adcplus(2,2);
printf("Reading DAC4 Volts\n");
adcplus(2,3);
printf("Reading DAC5 Volts\n");
adcplus(2,4);
Stats
->Ref Voltages(refv_cb)
-> 1.8V chip1
-> 1.8V chip2
-> 1.8V chip3
-> DMB GND
-> CFEB1 GND
-> CFEB2 GND
-> CFEB3 GND
-> CFEB4 GND
-> CFEB5 GND
-> Hist Refs (2 minutes)
Ref Voltage
Readout
of reference voltages.
printf("Reading 1.8V Chip 1\n");
adcplus(1,6);
printf("Reading 1.8V Chip 2\n");
adcplus(2,6);
printf("Reading 1.8V Chip 3\n");
adcminus(3,6);
printf("Reading DMB GND\n");
adcminus(3,0);
printf("Reading CFEB1 GND \n");
adcminus(3,1);
printf("Reading CFEB2 GND \n");
adcminus(3,2);
printf("Reading CFEB3 GND \n");
adcminus(3,3);
printf("Reading CFEB4 GND \n");
adcminus(3,4);
printf("Reading CFEB5 GND \n");
adcminus(3,5);
Stats
->Calib Info(calv_cb)
-> DAC Settings
-> DAC Channel
-> DAC Pattern
-> Int Cal DAC
-> Ext Cal DAC
-> Ext Cal DAC Prec.
-> Hist Int Cal
-> Hist Ext Cal
-> Hist Ext Cal Pres.
-> Hist Ext Compare
DAC Settings
Prints
present pulser DAC voltages.
DAC Channel
Prints
present pulser DAC channel.
DAC Pattern
Prints
present Buckeye shift pattern.
Int Cal DAC
Readback
of internal capacitor pulser voltage.
printf("Reading Internal Calib. DAC\n");
adcplus(2,7);
break;
Ext Cal DAC
Readback
of external (precision) capacitor pulser voltage.
printf("Reading External Calib. DAC\n");
adcminus(3,7);
break;
Ext Cal DAC Prec.
Precision
readback of external (precision) capacitor pulser voltage.
printf("Reading Precision Calib. DAC\n");
adc16(4,0);
break;
Hist Int Cal
Plots
histogram of internal capacitor pulser voltage.
histintcal(dp);
Hist Ext Cal
Plots
histogram of external (precision) capacitor pulser voltage.
histextcal(dp);
Hist Ext Cal Pres.
Plots
precision histogram of external (precision) capacitor pulser voltage.
histextcalpres(dp);
Hist Ext Compare
Histogram
comparison of precision vs normal readout of external (precision) capacitor
pulser voltage.
histcalcomp(dp);
Stat
->ID Codes(idcode_cb)
-> MB PROM userid
-> MB Virtex userid
-> MB PROM chipid
-> MB Virtex chipid
-> FEBs PROM userid
-> FEBs Virtex userid
-> FEBs PROM chipid
-> FEBs Virtex chipid
ID Codes(idcode_cb)
All FPGAs
and Proms have chip id's and user id's. User id's can be
read or
written.
MB PROM userid
mbpromuser(dp);
MB Virtex userid
mbfpgauser(dp);
MB PROM chipid
mbpromid(dp);
MB Virtex chipid
mbfpgaid(dp);
FEBs PROM userid
febpromuser(ALL,dp);
FEBs Virtex userid
febfpgauser(ALL,dp);
FEBs PROM chipid
febpromid(ALL,dp);
FEBs Virtex chipid
febfpgaid(ALL,dp);
Stats
->ReadBack FPGAs(readback_cb)
->Readback FPGA
->Readback MB Control FPGA
->Readback FEB's Control FPGA
FPGA
firmware can be read back and checked. These are not coded in
a
general way yet. An example of how to read back can be found in.
rdbkfpga();
Stats
->LV Brd (extern)(lvbrd_cb)
->LV Reg on
->LV Reg off
->LV Reg Rd
->read ADC(1,1)
LV Brd
Davis'
low voltage monitor board.
LV Reg on
Turn on
power.
lowv_on();
LV Reg off
Turn
off power.
lowv_off();
LV Reg Rd
Read
power on off status.
lowv_rdpwrreg();
read ADC(1,1)
Read
back all voltages.
lowv_dump();
*********************************************************************
Memories's
->Check All Mems(memall_cb)
->Mem 1(mem1_cb)
-> memchk
-> wrtfifox
-> wrtfifo_toggle
-> wrtfifo_123
-> readfifox
-> readfifo_chk
->Mem 2
->Mem 3
->Mem 4
->Mem 5
->Mem 6
->Mem 7
There
are seven FIFO memories on the DAQMB. Data is passed from the FE Boards,
and
trigger motherboard to these FIFOs when a LVL1 and LCT arrive in
time.
The DAQMB controller appends headers and tailers and send the data
to the
DDU. These routines check the operation of this memory.
Check All Mems(memall_cb)
Completely
check the memories for FIFO1-FIFO7. Note one cannot
simply
check overlap FIFO6 memory.
printf("Running Memchk\n");
err[1]=memchk(FIFO1);
errs+=err[1];
err[2]=memchk(FIFO2);
errs+=err[2];
err[3]=memchk(FIFO3);
errs+=err[3];
err[4]=memchk(FIFO4);
errs+=err[4];
err[5]=memchk(FIFO5);
errs+=err[5];
err[7]=memchk(FIFO7);
errs+=err[7];
memchk
Checks
a single FIFO.
errs=memchk(devnum);
wrtfifox
Writes
all FFFF's to a fifo.
wrtfifox(devnum,0x7fff);
wrtfifo_toggle
Writes
alternating 0x5555 and 0xaaaa to memory.
wrtfifo_toggle(devnum);
wrtfifo_123
Write a
count 0,1,2,3,... to memory.
wrtfifo_123(devnum);
readfifox
Reads
back a FIFOs memory.
readfifox(devnum,dp);
readfifo_chk
Reads
back and checks a fifos memory. In this case
it is
checking whether the memory has all FFFF's.
readfifox_chk(devnum,0x7fff);
Calibration
->DAC(dac_cb)
->set voltage
Calibration (External/Precision)
Calibration
consists of internal and external capacitors connected
to each
buckeye channel. Which capacitors are connected is controlled
by a 48
bit shift register on each buckeye. The three bits specific
to a
buckeye input channel can be set to the following modes: NORMAL,
LARGE,MEDIUM,SMALL,EXT,KILL.
NORMAL -
normal operation
EXT - external (precision)
capacitor
LARGE,MEDIUM,SMALL - internal capacitors
KILL -
short output stage
A
voltage is supplied to these capacitors by a precision DAC. Additionally
on can
set the LVL1/LCT to pulse timing in 5 nsecond increments. Both
interal
and external pulsing can be triggered either through the CCB
board
or through the DAQMB. The DAC has to be set and buckeyes shifted
before
one can fire the pulser.
set voltage
Set the
voltage on the precision pulse capacitors and trigger pulse capacitors.
set_dac(volt1,volt2,dp);
Calibration
->Buckey(buck_cb)
->shift zeros
->shift set chan
->shift in pattern
shift zeros
Shift
the buckeyes with NORMAL MODE.
preamp_initx(ALL,dp);
shift set chan
Turn on
EXT external (precision) capacitor mode on a single channel (one on each of six
buckeyes).
set_ext_chanx(schan,ALL,dp);
shift in pattern
Shift a
pattern read from a file into the buckeyes.
read_strip_pat(patfile,ALL,dp);
Calibration
->Pedestal(ped_cb)
->collect 100
->collect 1000
->collect 10000
->cap
collect 100
Collect
pedestal statistics for 100 samples.
printf("collect 100\n");
pedestals(100,dp);
collect 1000
Collect
pedestal statistics for 1000 samples.
printf("collect 1000\n");
pedestals(1000,dp);
collect 10000
Collect
pedestal statistics for 1000 samples.
printf("collect 10000\n");
pedestals(10000,dp);
cap
Collect
capacitor pedestals.
printf("cap\n");
cappeds(500,dp);
Calibration
->Pulser(pulser_cb)
-> single pulse
-> single hex dump
-> multi pulse
-> Check peaks and side chan.
-> Check Dead Chan.
-> Check Stuck Bits
-> Speed Test
single pulse
Pulse
once and plot charge.
snglpulplot(dp);
single hex dump
Pulse
once and dump event to disk.
snglpul_hexdump(dp);
multi pulse
Pulse
100 times.
multpulse(dp);
Check peaks and side chan.
Pulse
central peak and look at L/R cross talk.
multpulse(dp);
Check Dead Chan.
Check
for dead channels.
chk_dead_chan(dp);
Check Stuck Bits
Check for
stuck bits in the ADC. Pulse many times and
check
how often bits were used.
stkbits(dp);
Speed Test
Check
pulse and readin speed.
speed(dp);
Calibration
-> Linearity(lin_cb)
-> channel
-> all
channel
This
program for a single channel pulses changes the DAC setting repeats
in
order to check linearity. The results are histogrammed.
linpulse1(dp);
all
This
program for all channels pulses changes the DAC setting repeats
in
order to check linearity. The results are histogrammed.
linpulse2(dp);
Calibration
->Shape(shap_cb)
->channel
->all
channel
This
program pulses a single channel and then shifts the LCT/LVL1
to
pulse time by 5 nsecs and repeats giving a pulse shape sampled
every 5
nseconds. The output is histogrammed.
shappulse1(dp);
all
Same as
channel but works for all channels.
Calibration
->Bckpln(bckpln_cb)
->Pedestal
->Cap Peds
->Fast Peds
->Speed
Pedestal
Pedestals
taken using the CCB board pulse firing.
pedestals_rice(1000,dp);;
Cap Peds
Capacitor
pedestals using the CCB board pulse firing.
cappeds_rice(500,dp);
Fast Peds
A
faster method of taking pedestals using the CCB pulse firing.
pedestals_fast_rice(dp);
Speedspeed_rice(dp);
Another
speed test.
speed_rice(dp);
Trigger
->DAC(dac_cb)
->set voltage
Trigger (Internal Capacitors)
set voltage
Set the voltage on the precision pulse
capacitors and trigger pulse capacitors.
set_dac(volt1,volt2,dp);
Trigger
-> Patterns(pat_cb)
->set halfstrip
->set random event
->Global and DDU Reset
->Inject Charge
->Inject UCLA Pattern
->Trigger Threshold test
->Test Half Strips
->Test All Patterns
->Pulse Height/Patterns
set halfstrip
Pulse a
given half strip. In the routine below hlfstrp runs from 1-32
trighalfx(hlfstrp,dp);
set random event
Creats
a fake random track traversing the detector. Resulting charges
are
histogrammed.
trigroadsx(dp);
Global and DDU Reset
Not
needed anymore. Simple resets crucial components.
calctrl_fifomrst();
calctrl_global();
err=reset_ddu();
Inject Charge
Injects
and plots a single pulse.
snglinjplot(dp);
Inject UCLA Pattern
Injects
a pattern chosen by UCLA and plots it.
snglinjplot_ucla(dp);
Trigger Threshold test
An
attempt at a trigger threshold test.
trigthresh(dp);
Test Half Strips
Tests
all half strips.
test_half_strips(dp);
Test All Patterns
Tests a
set of patterns.
trigtest(dp);
Pulse Height/Patterns
trigpulse(dp);
Trigger
->Comp. Thresholds(comp_cb)
->All FEB set thresh.
->FEB1: set thresh.
->FEB2: set thresh.
->FEB3: set thresh.
->FEB4: set thresh.
->FEB5: set thresh.
All FEB set thresh.
Set all
FEB comparator chip thresholds.
set_comp_thresh(all,thresh,dp);
FEB1: set thresh.
Set
CFEB 1 comparator chip thresholds.
set_comp_thresh(F1SCAM,thresh,dp);
Trigger
->Bckpln(bckpln2_cb)
->Inject Charge
Use the
CCB board to inject charge.
snglinjplot_rice(dp);
Trigger
->Auto Test(auto_test_cb)
Routine
to check triads using an oscilliscope. Ignore.
Gigabit Ethernet Routines
Initializing:
init_ddu();
Resetting:
reset_ddu();
Ending:
close_ddu();
Receiving
data:
count=-1;
buf2=(char **)malloc(2);
count=read_ddu(buf2,dp);
if(count<1){
printf("No data from DDU\n");
return count;
}
buf=(unsigned short *)*buf2;
buf=buf+2;
Appendix I - Initializing JTAG
One
needs to setup a socket in order for the D360 low level routines to work.
This is
how to set up the socket.
/* now open D360(VME) sockets */
struct sockaddr_in serv_addr;
pname = argv[0];
/*
* Fill "serv_addr" with the address of the server we want to connect with
*/
bzero( (char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR);
serv_addr.sin_port = htons(SERV_TCP_PORT);
/*
* open a TCP socket ( an internet stream socket )
*/
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
fprintf(stderr,"jtag-client: can't open a stream socket");
/*
* connect to the server
*/
if( (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))) < 0)
fprintf(stderr,"jtag-client: can't connect to the server");
/****** program goes here ************/
close(fockfd);
Appendix II – Some Samples to do ‘PHYSICS’
events:
Example 1: Initialize the system.
Do the
following three steps in order:
1. Config à
Setup à Program All (BCKPLN)
2. Config à
Setup à Resets All (BKPLN)
3. Config à
Setup à Full Setup
Example2: Linearity test on Channel 1 amplifier (All CFEBs and All Buckeyes).
1. Calibration à
Buckeye à Shift Set Chan: enter 1 (Valid numbers are 0 to 15)
2. Calibration à
Linearity à Channel
Example3: To check the Channel 2 amplifier pulse:
1. Calibration à
DAC à Set Voltage (enter 2,2.
Valid value are from 0.0 to 5.0V)
2. Calibration à
Buckeye à Shift Set Chan (enter 2, valid values are from 0 to 15)
3. Calibration à
Shape à Channel
Example4: CFEB Noise level check
1. Calibration à
Pedestals à Collect 1000
Example5: Update CFEB1 FPGA firmware:
1. Config à
Load PROMs à Load/Prg FEB’s à FEB1: Load ISPROM (then choose the
SVF file)
2. Do all the three steps in example
1.
Example6: Read CFEB1 temperature:
1. Stats à
Temps à CFEB1 temp
Example7: Half strip pulsing on CFEB
1. Trigger à
DAC à Set Voltage (enter 2,2)
2. Pattern à
Set halfstrip (enter 5, valid numbers are from 0 to 31)
3. Pattern à
Inject Charge