Commit c665e3a9 authored by Evangelia Gousiou's avatar Evangelia Gousiou

rewrote all the functionality tests so as to make use of the pendulum rather…

rewrote all the functionality tests so as to make use of the pendulum rather than a Fine Delay board; like this the setup for the functionality and the calibration tests is the same
parent 58136c35
......@@ -5,10 +5,20 @@
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
LOGDIR=./log_fmctdc1ns5cha
sudo rmmod cp210x
cd ~/fmc-tdc-1ns-5cha-tst/pts
sudo insmod ./cp210x-driver/cp210x.ko
cd usbdriver
sudo ./usbtmc_load
cd ..
cd ~/fmc-tdc-1ns-5cha-tst/pts
LOGDIR=../logs/log_fmctdc1ns5cha
mkdir -p $LOGDIR
sudo rm -fr $LOGDIR/pts*
sudo rm -fr $LOGDIR/fmc-tdc-1ns-5cha-tst*
serial=$1
if [ x$1 = x"" ]; then
......@@ -47,7 +57,18 @@ do
echo "Test series run $nb_test out of $nb_test_limit"
echo " "
sudo ./pts.py -b FmcTdc1ns5cha -s $serial -e $extra_serial -t./test/fmctdc1ns5cha/python -l $LOGDIR 00 01 02 03 04 05 06 07 08 09 10 11 12
echo "--- Functionality tests ---"
sudo ./pts.py -b FmcTdc1ns5cha_funct -s $serial -e $extra_serial -t ../test/fmctdc1ns5cha/functionality/python -l $LOGDIR 00 #01 02 03 04 05 06 07 08 09 10 11 12
echo -n "Do you wish to continue with the calibration tests [y,n]? "
read reply
if [ "$reply" = "y" ]
then
echo "--- Calibration tests ---\n"
LOGDIR=../logs/log_fmctdc1ns5cha_calib
sudo ./pts.py -b FmcTdc1ns5cha_calib -s $serial -e $extra_serial -t ../test/fmctdc1ns5cha/calibration/python -l $LOGDIR 16 17 18 #13 14 15 16 17 18
fi
if [ "$nb_test" != "$nb_test_limit" ]
then
......
......@@ -56,7 +56,8 @@ do
echo "Test series run $nb_test out of $nb_test_limit"
echo " "
sudo ./pts.py -b FmcTdc1ns5cha -s $serial -e $extra_serial -t ../test/fmctdc1ns5cha/calibration/python -l $LOGDIR 00 01 02 03
echo "--- Calibration tests ---"
sudo ./pts.py -b FmcTdc1ns5cha_calib -s $serial -e $extra_serial -t ../test/fmctdc1ns5cha/calibration/python -l $LOGDIR 13 14 15 16 17 18
if [ "$nb_test" != "$nb_test_limit" ]
then
......
#!/bin/sh
# Copyright CERN, 2011
# Author: Evangelia Gousiou <egousiou@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
sudo rmmod cp210x
cd ~/pts_cleanup
sudo insmod ./cp210x-driver/cp210x.ko
cd usbdriver
sudo ./usbtmc_load
cd ..
LOGDIR=./log_fmctdc1ns5cha_wrcalib
mkdir -p $LOGDIR
sudo rm -fr $LOGDIR/pts*
serial=$1
if [ x$1 = x"" ]; then
echo -n "Please scan CERN serial number bar-code, then press [ENTER]: "
read serial
fi
if [ x$serial = x"" ]; then
serial=0000
fi
if [ -e serial.txt ]; then
sudo rm -f serial.txt
fi
echo $serial >> serial.txt
extra_serial=$2
if [ x$2 = x"" ]; then
echo -n "If needed input extra serial number and press [ENTER] OR just press [ENTER]: "
read extra_serial
fi
if [ x$extra_serial = x"" ]; then
extra_serial=0000
fi
echo " "
nb_test_limit=2
nb_test=1
while [ "$nb_test" -le "$nb_test_limit" ]
do
echo "--------------------------------------------------------------"
echo "Test series run $nb_test out of $nb_test_limit"
echo " "
sudo ./pts.py -b FmcTdc1ns5cha -s $serial -e $extra_serial -t./test/fmctdc1ns5cha/calibration/python -l $LOGDIR 00 01 02 03 04 05
if [ "$nb_test" != "$nb_test_limit" ]
then
echo " "
echo -n "Do you want to run the test series again [y,n]? "
read reply
if [ "$reply" != "y" ]
then
break
fi
fi
nb_test=$(($nb_test+1))
done
echo "--------------------------------------------------------------"
echo " "
echo -n "End of the test, do you want to switch the computer OFF? [y,n]"
read reply
if [ "$reply" = "y" ]
then
sudo poweroff
fi
......@@ -13,7 +13,7 @@ class CCP210x:
self.fd = open(device, 'wb')
def gpio_set(self, mask):
print("gpio_set %x" % mask),
#print("gpio_set %x" % mask),
f = array.array('L', [0])
f[0] = (mask << 8) | 0xff;
fcntl.ioctl(self.fd, 0x8001, f, 0)
......
......@@ -109,7 +109,7 @@ BOX_USB_DEVICE_ID = 0xea60 # CP210x Composite Device
TEMPID_FAMILY_CODE = 0x28
TEMP_THRES = 46.0
TEMP_THRES = 43.0
TEMP_RIPPLE = 0.3
FIFO_SIZE = 20
MEAS_SLEEP = 1
......
......@@ -58,7 +58,7 @@ from numpy import *
from ctypes import *
from datetime import datetime
# Add common modules location tp path
# Add common modules location to path
sys.path.append('../../../../pts/')
sys.path.append('../../../../pts/gnurabbit/python/')
sys.path.append('../../../../pts/common/')
......
#! /bin/bash
ln -s ch_calib.py test00.py
ln -s DAC_calib.py test01.py
ln -s write_eeprom.py test02.py
ln -s verify_calib.py test03.py
ln -s wrabbit_calib.py test04.py
ln -s wrabbit_write_eeprom.py test05.py
ln -s ch_calib.py test13.py
ln -s DAC_calib.py test14.py
ln -s write_eeprom.py test15.py
ln -s verify_calib.py test16.py
ln -s wrabbit_calib.py test17.py
ln -s wrabbit_write_eeprom.py test18.py
#! /bin/bash
rm -f test00.py
rm -f test01.py
rm -f test02.py
rm -f test03.py
rm -f test04.py
rm -f test05.py
rm -f test13.py
rm -f test14.py
rm -f test15.py
rm -f test16.py
rm -f test18.py
rm -f test18.py
rm -f test*.pyc
\ No newline at end of file
rm -f test*.pyc
rm -f test*.py~
......@@ -74,12 +74,12 @@ import math
from datetime import datetime
# Add common modules location to path
sys.path.append('../../../../')
sys.path.append('../../../../gnurabbit/python/')
sys.path.append('../../../../common/')
sys.path.append('../../../../common/cp210x')
sys.path.append('../../../../common/usb_box')
sys.path.append('../../../fmceeprom/python/')
sys.path.append('../../../../pts/')
sys.path.append('../../../../pts/gnurabbit/python/')
sys.path.append('../../../../pts/common/')
sys.path.append('../../../../pts/common/fmceeprom/python')
sys.path.append('../../../../pts/common/usb_box')
sys.path.append('../../../../pts/common/cp210x')
# Import common modules
......@@ -147,7 +147,7 @@ def main (default_directory='.'):
# Constants declaration
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/wrabbit_tdc.bin'
FPGA_LOADER_PATH = '../../../../gnurabbit/user/fpga_loader'
FPGA_LOADER_PATH = '../../../../pts/gnurabbit/user/fpga_loader'
FAMILY_CODE = 0x28
WRABBIT_CLK_LOCK_MASK = 0x10
WRABBIT_CALIB_FILENAME = "wrabbit_calib_data.txt"
......
......@@ -58,10 +58,12 @@ import os
import numpy as np
# Add common modules and libraries location to path
sys.path.append('../../../../')
sys.path.append('../../../../gnurabbit/python/')
sys.path.append('../../../../common/')
sys.path.append('../../../fmceeprom/python/')
sys.path.append('../../../../pts/')
sys.path.append('../../../../pts/gnurabbit/python/')
sys.path.append('../../../../pts/common/')
sys.path.append('../../../../pts/common/fmceeprom/python')
sys.path.append('../../../../pts/common/usb_box')
sys.path.append('../../../../pts/common/cp210x')
# Import common modules
from ptsexcept import *
......@@ -106,9 +108,9 @@ def main (default_directory='.'):
start_test_time = time.time()
# Constants declaration
FMC_TDC_ADDR = '1a39:0004/1a39:0004@0001:0000'#'1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc.bin'#spec-fmc-tdcDBG.bin'
FPGA_LOADER_PATH = '../../../../gnurabbit/user/fpga_loader'
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc.bin'
FPGA_LOADER_PATH = '../../../../pts/gnurabbit/user/fpga_loader'
# SPEC object declaration
spec = rr.Gennum()
......
......@@ -15,11 +15,11 @@
## |
## Description Testing of the communication with the ACAM chip IC8 of the TDC board. |
## The test configures the ACAM chip and then checks the status of all its registers.|
## In detal these lines are tested: TDC_D[27..0], TDC_ADR[3..0], RESET_N, TDC_WRN, |
## In detail these lines are tested: TDC_D[27..0], TDC_ADR[3..0], RESET_N, TDC_WRN, |
## TDC_RDN, TDC_CSN, TDC_OEN |
## |
## |
## FW to load .bin |
## FW to load tdc_allothertests.bit |
## Authors Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
## Website http://www.ohwr.org/projects/pts |
## Date 11/01/2013 |
......@@ -50,16 +50,14 @@ import math
from datetime import datetime
# Add common modules location tp path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
sys.path.append('../../../../pts/')
sys.path.append('../../../../pts/gnurabbit/python/')
sys.path.append('../../../../pts/common/')
# Import common modules
from ptsexcept import *
import rr
import csr
# Import specific modules
import fmc_tdc
......@@ -69,11 +67,16 @@ import fmc_tdc
def main (default_directory='.'):
start_test_time = time.time()
#-----> PCIe address, firmware, loader constants
# Constants declaration
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_allothertests.bit'
FPGA_LOADER_PATH = '../../../gnurabbit/user/fpga_loader'
FPGA_LOADER_PATH = '../../../../pts/gnurabbit/user/fpga_loader'
#-----> FPGA initializations
# SPEC object declaration
spec = rr.Gennum()
......@@ -81,8 +84,9 @@ def main (default_directory='.'):
print "\n-------------------------------------------------------------------"
print "----------------------------- FMC TDC -----------------------------"
print "-------------------- ACAM IC8 communication test ------------------\n"
print ("Testing of the communication with the ACAM chip IC8."
" The test\nconfigures the ACAM and then checks the status of its registers.\n")
print ("Testing of the communication with the ACAM chip IC8.\n"
"The test configures the ACAM and then checks the status of all\n"
"its registers.\n")
print "\n_______________________________Info______________________________\n"
print "FMC TDC address to parse: %s"%(FMC_TDC_ADDR)
......@@ -121,6 +125,8 @@ def main (default_directory='.'):
else:
print('Access to TDC core OK')
#-----> TDC configuration
# TDC configuration
print "\n__________________________Configuration__________________________\n"
tdc.config_acam()
......@@ -152,8 +158,10 @@ def main (default_directory='.'):
print (msg)
raise PtsError (msg)
os.close(spec.fd)
print "\n-----------------------------------------------------------------\n\n\n"
print "\n\n--------------------------------"
end_test_time = time.time()
print "Test elapsed time: %.2f seconds\n\n\n" % (end_test_time-start_test_time)
if __name__ == '__main__' :
......
......@@ -15,8 +15,9 @@
## |
## Description Testing of the ACAM IC8 timestamps, TDC_START_FPGA signal, TDC_STOP signals, |
## TDC_INT signal, TDC_EMPTY_FLAG signals. |
## The Fine Delay is used as pulse generator sending pulses to all the TDC channels. |
## The test is retrieving the pulses and is checking their accuracy. |
## The test is using the Pendulum as pulse generator that in collaboration with the |
## Timetech Fanout and the USB-interconnection-box is sending pulses to each one of |
## the TDC channels. The test is retrieving the pulses and is checking their accuracy|
## |
## |
## FW to load tdc_allothertests.bit |
......@@ -48,23 +49,50 @@ import sys
import time
import os
import math
from numpy import *
from ctypes import *
from datetime import datetime
# Add common modules location tp path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
# Add common modules location to path
sys.path.append('../../../../pts/')
sys.path.append('../../../../pts/gnurabbit/python/')
sys.path.append('../../../../pts/common/')
sys.path.append('../../../../pts/common/usb_box')
sys.path.append('../../../../pts/common/cp210x')
# Import common modules
from ptsexcept import *
import rr
import csr
# Import specific modules
import fmc_tdc
sys.path.append('../../../common/fmc_delay/software/python/')
import fdelay_lib
from cp210x_eeprom import *
from PendulumCNT91 import *
from calibr_box import *
from find_usb_tty import *
# Pendulum
PENDULUM = "/dev/usbtmc1"
USB_DEVICE = "/dev/ttyUSB0"
RS232_BAUD = 57600
def pendulum_output_on(meas):
meas.write("OUTP:TYPE PULS")
meas.write("SOUR:PULS:PER 0.008")
meas.write("SOUR:PULS:WIDT 0.0002")
return (1)
def pendulum_output_off(meas):
meas.write("OUTP:TYPE OFF")
return (1)
# USB-interconnection-box
BOX_USB_VENDOR_ID = 0x10c4 # Cygnal Integrated Products, Inc.
BOX_USB_DEVICE_ID = 0xea60 # CP210x Composite Device
NUM_OF_TSTAMPS = 10 # number of fill-ups of the TDC memory
# ex NUM_OF_TSTAMPS = 10, means aquisition
# of 2560 timestamps; in this setup this means
# 640 rising edge timestamps per channel
##-------------------------------------------------------------------------------------------------
## Main --
......@@ -72,27 +100,28 @@ import fdelay_lib
def main (default_directory='.'):
# Constants declaration
start_test_time = time.time()
#-----> PCIe address, firmware, loader constants
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_allothertests.bit'
FMC_DELAY_ADDR = '1a39:0004/1a39:0004@0005:0000'
FMC_DELAY_BITSTREAM_PATH = '../firmwares/fmc_delay_spec.bin'
FPGA_LOADER_PATH = '../../../gnurabbit/user/fpga_loader'
FMC_TDC_CHANNEL_NB = 5
FPGA_LOADER_PATH = '../../../../pts/gnurabbit/user/fpga_loader'
#-----> FPGA initializations
# SPEC object declaration
spec = rr.Gennum()
#-----> TDC
# Bind SPEC object to FMC TDC card
print "\n-------------------------------------------------------------------"
print "----------------------------- FMC TDC -----------------------------"
print "-------------------- TDC_STOP channels test -----------------------\n"
print ("Test of the accuracy of the ACAM timestamps for each one of the channels.\n"
"The test is using the Fine Delay board as pulse generator, sending\n"
"several pulses to each one of the TDC channels. The test configures\n"
"the ACAM chip and then retrieves and evaluates the generated timestamps.\n")
print "---------------------- ACAM accuracy test -------------------------\n"
print ("Test of the accuracy of the ACAM timestamps for each one of the\n"
"channels. The test is using the Pendulum as pulse generator that\n"
"in collaboration with the Timetech Fanout and the\n"
"USB-interconnection-box is sending pulses to each one of the TDC\n"
"channels. The test configures the ACAM chip and then retrieves\n"
"and evaluates the generated timestamps.\n")
print "\n_______________________________Info______________________________\n"
print "FMC TDC address to parse: %s"%(FMC_TDC_ADDR)
for name, value in spec.parse_addr(FMC_TDC_ADDR).iteritems():
......@@ -106,10 +135,6 @@ def main (default_directory='.'):
bitstream = os.path.join(default_directory, FMC_TDC_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
time.sleep(1)
firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
bitstream = os.path.join(default_directory, FMC_TDC_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
time.sleep(1)
print "Firmware loaded!"
# TDC object declaration
......@@ -119,17 +144,17 @@ def main (default_directory='.'):
bitstream_type = tdc.read_bitstream_type()
if(bitstream_type == 0xFFFFFFFF):
msg = ("FATAL ERROR: No access to TDC core")
os.close(spec.fd)
print (msg)
raise PtsCritical (msg)
raise PtsError (msg)
if(bitstream_type != 0x1):
msg = ("FATAL ERROR: Wrong bitstream type loaded")
os.close(spec.fd)
msg = ("FATAL ERROR: Wrong bitstream type loaded 0x%08X") %bitstream_type
print (msg)
raise PtsCritical (msg)
raise PtsError (msg)
else:
print('Access to TDC core OK')
#-----> ACAM and TDC configuration
# Configure ACAM and TDC core registers
print "\n__________________________Configuration__________________________\n"
tdc.config_acam()
......@@ -140,9 +165,7 @@ def main (default_directory='.'):
print "ACAM IC8: Status register OK"
else:
msg = ("ERROR: ACAM IC8: No communication")
os.close(spec.fd)
print (msg)
raise PtsError (msg)
acam_readback_regs = []
acam_readback_regs = tdc.readback_acam_config()
for i in range(len(tdc.ACAM_READBACK_REGS)):
......@@ -150,174 +173,162 @@ def main (default_directory='.'):
print "ACAM IC8: reg 0x%02X: 0x%08X OK"%(tdc.ACAM_READBACK_ADDR[i], acam_readback_regs[i])
else:
msg = ("ERROR: ACAM IC8: Configuration registers failure; reg 0x%2X: received 0x%8X, expected 0x%8X"%(tdc.ACAM_READBACK_ADDR[i], acam_readback_regs[i], tdc.ACAM_READBACK_REGS[i]))
os.close(spec.fd)
print (msg)
raise PtsError (msg)
# DAC
tdc.configure_mezz_dac(0xA9CF)
# Enable terminations of channels 1,2,3,4
# channels 4 and 5 are receiving the same Fine Delay pulse; only channel 5 termination activated
tdc.enable_channels()
tdc.channel_term(1, 1)
tdc.channel_term(2, 1)
tdc.channel_term(3, 1)
tdc.channel_term(4, 1)
# Enable timestamps aquisition (TDC_START_FPGA pulse sent at this step)
tdc.start_acq()
# Interrupts
print "\n____________________________IRQs_________________________________\n"
print('Set IRQ enable mask: %.4X')%tdc.set_irq_en_mask(0x1F)
tdc.set_irq_tstamp_thresh(0x100)
tdc.set_irq_time_thresh(0xFFFFF)
#-----> USB-interconnection-box
# Communication and setup of Interconnection box
print "\n_____________________USB interconnection box______________________\n"
box_tty = CttyUSB().find_usb_tty(BOX_USB_VENDOR_ID, BOX_USB_DEVICE_ID)
print("Device: %s" % box_tty[0])
box = CCalibr_box(box_tty[0])
box.select_trigger_loopback(0)
box.select_output(4)
#-----> Fine Delay
# Bind SPEC object to FMC Fine Delay card
print "\n___________________________Fine Delay____________________________"
print "\nFine Delay initializations.."
print "Fine Delay address to parse %s"%(FMC_DELAY_ADDR)
for name, value in spec.parse_addr(FMC_DELAY_ADDR).iteritems():
print "%s:0x%04X"%(name, value)
spec.bind(FMC_DELAY_ADDR)
# Load FMC Fine Delay firmware
print "\nLoading FMC Fine Delay firmware...",
firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
bitstream = os.path.join(default_directory, FMC_DELAY_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
time.sleep(2)
print "Firmware loaded!"
time.sleep(2)
# Fine Delay object declaration
#-----> Pendulum
# Communication with Pendulum
print "\n__________________________USB Pendulum_____________________________\n"
try:
fdelay = fdelay_lib.FineDelay(spec.get_fd())
except:
msg = ("ERROR: Fine Delay board Initiliazation failed")
os.close(spec.fd)
print (msg)
raise PtsError (msg)
meas = PendulumCNT91(PENDULUM)
except OSError:
raise PtsError('CNT-91 is not switched on or badly connected, aborting.')
a = pendulum_output_off(meas)
# Set UTC and Coarse time in the Fine Delay
fdelay.set_time(0, 0)
fd_time = fdelay_lib.fd_timestamp()
fd_time = fdelay.get_time()
# Configure the Fine Delay as a pulse generator
enable = 1
t_start_coarse = 0
width = 100000 # pulse width 100 ns
delta = 200000 # rising edges every 200 ns
count = 6
#-----> TDC
# Enable channels and start timestamps acquisition (TDC_START_FPGA pulse sent at this step)
print "\n______________________ACAM acquisition start________________________\n"
# Enable channels and terminations of all channels
tdc.enable_channels()
tdc.channel_term(1, 1)
tdc.channel_term(2, 1)
tdc.channel_term(3, 1)
tdc.channel_term(4, 1)
tdc.channel_term(5, 1)
# string to keep the ERROR messages from all the channels
all_msg = ""
tdc.start_acq()
print ("Sending pulses of period 8 ms to each TDC STOP channel")
for i in range(4): # one iteration per channel;
# channels 4 and 5 receive pulses at the same time
# string to keep the ERROR messages from all the channels
all_msg = ""
time.sleep(0.5) # needed between iterations
#-----> Sending pulses to all the channels
for i in range(4): # for the 4 pairs of channels (1,2), (1,3), (1,4), (1,5)
otherch = i+1
r_edge_timestamps_ch1 = []
r_edge_timestamps_otherch = []
all_measurs = []
r_edge_timestamps = []
r_edge_timestamps_ch5 = []
all_measurs = []
all_measurs_ch5 = []
# USB-interconnection-box
box.select_trigger_loopback(0)
box.select_output(4-i)
#-----> Fine Delay
# Bind SPEC object to FMC Fine Delay card
spec.bind(FMC_DELAY_ADDR)
channel = i+1
t_start_utc = fdelay.get_time().utc+1 # starting in 1 sec
fdelay.conf_pulsegen(channel, enable, t_start_utc, t_start_coarse, width, delta, count)
# pendulum output on
a = pendulum_output_on(meas)
#-----> TDC
# Bind SPEC object to FMC TDC card
spec.bind(FMC_TDC_ADDR)
# Check if timestamps arrived
print "\n_________________________TDC_STOP%d test____________________________\n" %(i+1)
time.sleep(1.5)
print "The time now is : %s" %datetime.now()
print "The temperature now is : %3.3f°C" %tdc.mezz_get_temp()
print "Fine Delay sent : %d pulses of 200ns period"%(count)
print "TDC Write pointer : %d"%(tdc.get_pointer())
if (tdc.get_pointer()) != 0:
# TDC acquisition of NUM_OF_TSTAMPS*64 timestamps per channel
for j in range(NUM_OF_TSTAMPS):
tdc.check_irq(0)
timestamps, data = tdc.get_timestamps(0)
# keep only rising edge timestamps belonging to channel under test
# keep only rising edge timestamps
for m in range(len(timestamps)):
if ((timestamps[m][2] == 1) and (timestamps[m][1] == channel-1)):
r_edge_timestamps.append(timestamps[m][0])
if ((timestamps[m][2] == 1) and (timestamps[m][1] == 4)):
r_edge_timestamps_ch5.append(timestamps[m][0])
# check number of pulses arrived
if ((len(r_edge_timestamps)) == 0):
msg = (("ERROR: TDC_STOP%d: No pulse arrived ") %channel)
print (msg)
all_msg+=msg
if ((len(r_edge_timestamps_ch5) == 0) and i == 3):
msg = ("ERROR: TDC_STOP5: No pulse arrived ")
print (msg)
all_msg+=msg
elif (len(r_edge_timestamps)) == 6:
print "Number of rising edge timestamps : %d"%(len(r_edge_timestamps))
else:
msg = (("ERROR: TDC_STOP%d: Unexpected number of pulses arrived; expected 6, arrived %d ")%(channel, (len(r_edge_timestamps))))
if (timestamps[m][2] == 1) and (timestamps[m][1] == 0): # rising tstamps ch1
r_edge_timestamps_ch1.append(timestamps[m][0])
elif (timestamps[m][2] == 1) and (timestamps[m][1] == otherch): # rising tstamps pair channel
r_edge_timestamps_otherch.append(timestamps[m][0])
# clear interrupt
tdc.clear_irq_src(int(math.log(tdc.get_irq_src(),2)))
# pendulum output off
a = pendulum_output_off(meas)
# keep only rising edge timestamps
tdc_write_pointer_now = tdc.get_pointer()
tdc_overflows_now = tdc.get_overflow_counter()
if tdc_overflows_now != NUM_OF_TSTAMPS*(i+1):
msg = ("ERROR: Unexpected error with interrupts; expected overflows: %d; received overflows: %d")%((NUM_OF_TSTAMPS*(i+1)),tdc_overflows_now)
print (msg)
all_msg+=msg
# if corrent number of timestamps has arrived, continue with the math
if (len(r_edge_timestamps)) == 6:
# evaluate timestamps: for each pulse, calculate the delta; should be 200 ns
for k in range(0,len(r_edge_timestamps),2):
measur = r_edge_timestamps[k+1] - r_edge_timestamps[k]
all_measurs.append(measur)
# average the delta from the 6 pulses
avg = (sum(all_measurs, 0.0) / len(all_measurs))
if (avg > 198800) and (avg < 201200): # +/-1200 ps acceptance limits (+/-500 ps from FD plus +/-700ps from TDC)
print "Pulse delta measurement : %.2f ps"%(avg)
else:
msg = (("ERROR: ACAM IC8: Wrong timestamps; pulse delta %.2f ps is outside accepted limits [198800 ps..201200 ps] ") %avg[i])
print (msg)
all_msg+=msg
if i == 3: # for channel 5 that receives pulses along with channel 4
print "\n________________________TDC_STOP5 test__________________________\n"
# check number of pulses arrived
if (len(r_edge_timestamps_ch5)) == 0:
msg = ("ERROR: TDC_STOP5: No pulse arrived ")
# data manipulation for channel 1
if i == 0:
print "\n_________________________TDC_STOP%d test____________________________\n" %(i+1)
print "Ch1 tstamps : %d"%(len(r_edge_timestamps_ch1))
print "TDC write pointer: %d"%(tdc_write_pointer_now)
print "TDC overflows : %d"%(tdc_overflows_now)
measurs_ch1 = []
# check number of pulses arrived
if (len(r_edge_timestamps_ch1) > 63*NUM_OF_TSTAMPS) or (len(r_edge_timestamps_ch1) < 60*NUM_OF_TSTAMPS):
r_edge_timestamps_ch1.sort()
# analyse the timestamps for Ch1
for k in range(0, len(r_edge_timestamps_ch1)-1, 1):
measur = r_edge_timestamps_ch1[k+1] - r_edge_timestamps_ch1[k]
if (measur < 8999995000) or (measur < 9000005000):
measurs_ch1.append (measur)
print "samples : %d"%(len(measurs_ch1))
# evaluate the timestamps for Ch1
if (len(measurs_ch1) < 600) or (len(measurs_ch1) > 650):
msg = ("ERROR: Ch1 received %d timestamps of 8ms period; expected: around %d \n")%(len(measurs_ch1), 64*NUM_OF_TSTAMPS)
print (msg)
all_msg+=msg
elif (len(r_edge_timestamps_ch5)) == 6:
print "Number of rising edge timestamps : %d"%(len(r_edge_timestamps_ch5))
else:
msg = (("ERROR: TDC_STOP5: Unexpected number of pulses arrived; expected 6, arrived %d ")%((len(r_edge_timestamps_ch5))))
print (msg)
all_msg+=msg
if ((len(r_edge_timestamps_ch5)) == 6):
# channel 5: for each pulse, calculate the delta; should be 200 ns
for k in range(0,len(r_edge_timestamps_ch5),2):
measur = r_edge_timestamps_ch5[k+1] - r_edge_timestamps_ch5[k]
all_measurs_ch5.append(measur)
avg = ((sum(measurs_ch1, 0.0) / len(measurs_ch1))/1e9) # in ms
print "average : %.2f ms"%(avg)
print "span : %.2f ps"%((max(measurs_ch1))-(min(measurs_ch1)))
print "max iter %d %.2f ps"%(measurs_ch1.index(max(measurs_ch1)), (max(measurs_ch1)))
print "min iter %d %.2f ps"%(measurs_ch1.index(min(measurs_ch1)), (min(measurs_ch1)))
print ("\nACAM Ch1 OK! Received %d timestamps of average period %.2f ms\n\n")%(len(measurs_ch1), avg)
else:
msg = ("ERROR: Ch1 registered timestamps: %d; expected: around %d \n")%(len(r_edge_timestamps_ch1), 64*NUM_OF_TSTAMPS)
print (msg)
all_msg+=msg
# channel 5: average the delta from the 6 pulses
avg = ((sum(all_measurs_ch5, 0.0) / len(all_measurs_ch5)))
if (avg > 198800) and (avg < 201200):
print "Pulse delta measurement : %.2f ps"%(avg)
else:
msg = (("ERROR: ACAM IC8: Wrong timestamps; pulse delta %.2f ps is outside accepted limits [198800 ps..201200 ps] ") %avg)
print (msg)
all_msg+=msg
# data manipulation for the other channel
print "_________________________TDC_STOP%d test____________________________\n" %(i+2)
print "Ch%d tstamps : %d"%(i+2, len(r_edge_timestamps_otherch))
print "TDC write pointer: %d"%(tdc_write_pointer_now)
print "TDC overflows : %d"%(tdc_overflows_now)
measurs_otherch = []
if len(r_edge_timestamps_otherch) > 63*NUM_OF_TSTAMPS:
r_edge_timestamps_otherch.sort()
for k in range(0, len(r_edge_timestamps_otherch)-1, 1):
measur = r_edge_timestamps_otherch[k+1] - r_edge_timestamps_otherch[k]
if (measur < 8999995000) or (measur < 9000005000):
measurs_otherch.append (measur)
print "samples : %d"%(len(measurs_otherch))
# evaluate the timestamps for Ch1
if (len(measurs_otherch) < 630) or (len(measurs_otherch) > 650):
msg = ("ERROR: Ch%d received %d timestamps of 8ms period; expected: around %d \n")%(i+2, len(measurs_otherch), 64*NUM_OF_TSTAMPS)
print (msg)
all_msg+=msg
else:
avg = ((sum(measurs_otherch, 0.0) / len(measurs_otherch))/1e9) # in ms
print "average : %.2f ms"%(avg)
print "span : %.2f ps"%((max(measurs_otherch))-(min(measurs_otherch)))
print "max iter %d %.2f ps"%(measurs_otherch.index(max(measurs_otherch)), (max(measurs_otherch)))
print "min iter %d %.2f ps"%(measurs_otherch.index(min(measurs_otherch)),(min(measurs_otherch)))
print ("\nACAM Ch%d OK! Received %d timestamps of average period %.2f ms\n\n")%(i+2, len(measurs_otherch), avg)
else:
msg = ("ERROR: Ch%d registered timestamps: %d; expected: around %d \n")%(i+2, len(r_edge_timestamps_otherch), 64*NUM_OF_TSTAMPS)
print (msg)
all_msg+=msg
del r_edge_timestamps
del all_measurs
if (all_msg != ""):
os.close(spec.fd)
......@@ -325,8 +336,9 @@ def main (default_directory='.'):
raise PtsError (all_msg)
os.close(spec.fd)
print "\n-----------------------------------------------------------------\n\n\n"
print "\n--------------------------------"
end_test_time = time.time()
print "Test elapsed time: %.2f seconds\n\n\n" % (end_test_time-start_test_time)
if __name__ == '__main__' :
......
......@@ -15,16 +15,17 @@
## |
## Description Testing of the TDC_ERR signal coming from the ACAM. |
## Through the configuration register 11, the ERR flag is configured to get activated|
## upon overflow on the interface FIFOs; an overflow occurs when the timestamps |
## arrival rate is higher than 31.25MHz. |
## The test is using the Fine Delay as pulse generator sending pulses to the five |
## channels with a total rate of 100MHz and is monitiring the TDC_ERR signal. |
## upon overflow on the Hit FIFOs; an overflow occurs when the timestamps arrival |
## arrival rate is higher than 31.25 MHz. |
## The test is using the Pendulum as pulse generator that in collaboration with the |
## Timetech Fanout and the USB-interconnection-box is sending pulses at 50 MHz to two|
## TDC channels simultaneously and is monitoring the TDC_ERR signal. |
## |
## The TDC_ERR signal can be accessed at PCIe address: 0xC0048 |
## The TDC_ERR register can be reset by writing '1' at PCIe address: 0xC004C |
## |
## |
## FW to load .bin |
## FW to load tdc_allothertests.bit |
## Authors Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
## Website http://www.ohwr.org/projects/pts |
## Date 11/01/2013 |
......@@ -55,22 +56,41 @@ import os
import math
from datetime import datetime
# Add common modules location tp path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
sys.path.append('../../../../pts/')
sys.path.append('../../../../pts/gnurabbit/python/')
sys.path.append('../../../../pts/common/')
sys.path.append('../../../../pts/common/usb_box')
sys.path.append('../../../../pts/common/cp210x')
# Import common modules
from ptsexcept import *
import rr
import csr
from cp210x_eeprom import *
from PendulumCNT91 import *
from calibr_box import *
from find_usb_tty import *
import fmc_tdc
# Pendulum
PENDULUM = "/dev/usbtmc1"
USB_DEVICE = "/dev/ttyUSB0"
RS232_BAUD = 57600
# Import specific modules
import fmc_tdc
sys.path.append('../../../common/fmc_delay/software/python/')
import fdelay_lib
def pendulum_output_on(meas):
meas.write("OUTP:TYPE PULS")
meas.write("SOUR:PULS:PER 0.00000002")
meas.write("SOUR:PULS:WIDT 0.00000001")
return (1)
def pendulum_output_off(meas):
meas.write("OUTP:TYPE OFF")
return (1)
# USB-interconnection-box
BOX_USB_VENDOR_ID = 0x10c4 # Cygnal Integrated Products, Inc.
BOX_USB_DEVICE_ID = 0xea60 # CP210x Composite Device
##-------------------------------------------------------------------------------------------------
......@@ -79,33 +99,34 @@ import fdelay_lib
def main (default_directory='.'):
# Constants declaration
start_test_time = time.time()
#-----> PCIe address, firmware, loader constants
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_allothertests.bit'
FMC_DELAY_ADDR = '1a39:0004/1a39:0004@0005:0000'
FMC_DELAY_BITSTREAM_PATH = '../firmwares/fmc_delay_spec.bin'
FPGA_LOADER_PATH = '../../../gnurabbit/user/fpga_loader'
FPGA_LOADER_PATH = '../../../../pts/gnurabbit/user/fpga_loader'
#-----> FPGA constants
FMC_TDC_CHANNEL_NB = 5
ERRFLAG_BASE = 0xC0000
ERRFLAG_REG = 0x48
RST_ERRFLAG_REG = 0x4C
#-----> FPGA initializations
# SPEC object declaration
spec = rr.Gennum()
#-----> TDC
# Bind SPEC object to FMC TDC card
print "\n-------------------------------------------------------------------"
print "----------------------------- FMC TDC -----------------------------"
print "-------------------- TDC ACAM ERROR FLAG test ---------------------\n"
print ("Testing of the ACAM TDC_ERR signal. The ERR flag is configured to\n"
"get activated upon overflow on the interface FIFOs; an overflow\n"
"occurs when the timestamps arrival rate is higher than 31.25MHz.\n"
"The test is using the Fine Delay as pulse generator sending pulses\n"
"to the all the TDC channels with a total rate of 100MHz and is\n"
"monitiring the TDC_ERR signal.\n")
"get activated upon overflow on the Hit FIFOs; an overflow occurs\n"
"when the timestamps arrival rate is higher than 31.25 MHz.\n"
"The test is using the Pendulum as pulse generator sending pulses\n"
"to two TDC channels simultaneously at a rate of 50 MHz and\n"
"is monitoring the TDC_ERR signal.\n")
print "\n_______________________________Info______________________________\n"
print "FMC TDC address to parse: %s"%(FMC_TDC_ADDR)
......@@ -139,12 +160,14 @@ def main (default_directory='.'):
raise PtsCritical (msg)
if(bitstream_type != 0x1):
msg = ("FATAL ERROR: Wrong bitstream type loaded")
os.close(spec.fd)
#os.close(spec.fd)
print (msg)
raise PtsCritical (msg)
#raise PtsCritical (msg)
else:
print('Access to TDC core OK')
#-----> ACAM configuration
# Configure ACAM and TDC core registers
print "\n__________________________Configuration__________________________\n"
tdc.config_acam()
......@@ -169,15 +192,17 @@ def main (default_directory='.'):
print (msg)
raise PtsError (msg)
# Enable terminations of channels 1,2,3,4
# channels 4 and 5 are receiving the same Fine Delay pulse; only channel 4 termination activated
#-----> TDC configuration
# Enable terminations of channels 1,2,3,4,5
tdc.enable_channels()
tdc.channel_term(1, 1)
tdc.channel_term(2, 1)
tdc.channel_term(3, 1)
tdc.channel_term(4, 1)
tdc.channel_term(5, 1)
# Enable timestamps aquisition (TDC_START_FPGA pulse sent at this step)
# Enable timestamps acquisition (TDC_START_FPGA pulse sent at this step)
tdc.start_acq()
# Check Effflag register
......@@ -193,78 +218,55 @@ def main (default_directory='.'):
print ("ACAM Error Flag initial value: 0x%08X OK" %(acam_errflag_init))
#-----> Fine Delay
# Bind SPEC object to FMC Fine Delay card
print "\n___________________________Fine Delay____________________________"
print "\nFine Delay initializations.."
print "Fine Delay address to parse %s"%(FMC_DELAY_ADDR)
for name, value in spec.parse_addr(FMC_DELAY_ADDR).iteritems():
print "%s:0x%04X"%(name, value)
spec.bind(FMC_DELAY_ADDR)
#-----> USB-interconnection-box
# Communication and setup of Interconnection box
print "\n_____________________USB interconnection box______________________\n"
box_tty = CttyUSB().find_usb_tty(BOX_USB_VENDOR_ID, BOX_USB_DEVICE_ID)
print("Device: %s" % box_tty[0])
box = CCalibr_box(box_tty[0])
box.select_trigger_loopback(0)
box.select_output(4)
# Load FMC Fine Delay firmware
print "\nLoading FMC Fine Delay firmware...",
sys.stdout.flush()
firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
bitstream = os.path.join(default_directory, FMC_DELAY_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
time.sleep(1)
print "Firmware loaded!"
# Fine Delay object declaration
#-----> Pendulum
# Communication with Pendulum
print "\n__________________________USB Pendulum_____________________________\n"
try:
fdelay = fdelay_lib.FineDelay(spec.get_fd())
except:
msg = ("ERROR: Fine Delay board Initiliazation failed")
os.close(spec.fd)
print (msg)
raise PtsError (msg)
meas = PendulumCNT91(PENDULUM)
except OSError:
raise PtsError('CNT-91 is not switched on or badly connected, aborting.')
# Set UTC and Coarse time in the Fine Delay
fdelay.set_time(0, 0)
fd_time = fdelay_lib.fd_timestamp()
fd_time = fdelay.get_time()
# Configure the Fine Delay as a pulse generator
enable = 1
t_start_coarse = 0
width = 50000 # pulse width 50 ns
delta = 100000 # rising edges every 100 ns
count = 1000
# sending pulses to all the channels, so as to trigger the Error Flag of the Interface FIFOs
print "\n____________________Fine Delay sending pulses____________________"
print "\n...pulses being sent to all the channels at a rate > 40MHz\n"
t_start_utc = fdelay.get_time().utc+1
fdelay.conf_pulsegen(1, enable, t_start_utc, t_start_coarse, width, delta, count)
fdelay.conf_pulsegen(2, enable, t_start_utc, t_start_coarse, width, delta, count)
fdelay.conf_pulsegen(3, enable, t_start_utc, t_start_coarse, width, delta, count)
fdelay.conf_pulsegen(4, enable, t_start_utc, t_start_coarse, width, delta, count)
# Pendulum output on
a = pendulum_output_on(meas)
# Pendulum sending pulses
time.sleep(5)
#-----> TDC
# Bind SPEC object to FMC TDC card
spec.bind(FMC_TDC_ADDR)
# Pendulum outsput off
a = pendulum_output_off(meas)
#-----> Check Errflag
# Check if timestamps arrived
print "\n______________________ACAM ErrorFlag test________________________\n"
print "The time now is : %s" %datetime.now()
print "The temperature now is : %3.3f°C" %tdc.mezz_get_temp()
print "Fine Delay sent : 1000 pulses to each TDC channel"
print "TDC Write pointer : %d"%(tdc.get_pointer())
print "TDC overflows counter : %d"%(tdc.get_overflow_counter())
if ((ERRFLAG_BASE.rd_reg(ERRFLAG_REG)) != 0):
print ("ACAM Error Flag : 0x%08X OK!" %(ERRFLAG_BASE.rd_reg(ERRFLAG_REG)))
else:
msg = ("ERROR: ACAM IC8: Error Flag: not activated as expected")
msg = ("ERROR: ACAM IC8: Error Flag: not activated as expected: 0x%08X")%(ERRFLAG_BASE.rd_reg(ERRFLAG_REG))
os.close(spec.fd)
print (msg)
raise PtsError (msg)
a = pendulum_output_off(meas)
os.close(spec.fd)
print "\n-----------------------------------------------------------------\n\n\n"
print "\n\n--------------------------------"
end_test_time = time.time()
print "Test elapsed time: %.2f seconds\n\n\n" % (end_test_time-start_test_time)
if __name__ == '__main__' :
......
......@@ -14,16 +14,18 @@
##-------------------------------------------------------------------------------------------------
## |
## Description Testing of the ENABLE_INPUTS signal. |
## The Fine Delay is used as pulse generator sending pulses to each one of the TDC |
## channels. On the TDC board the ACAM chip is registering the arriving pulses. |
## The test is using the Pendulum as pulse generator that in collaboration with the |
## Timetech Fanout and the USB-interconnection-box is sending pulses to each one of |
## the TDC channels. |
## On the TDC board the ACAM chip is registering the arriving pulses. |
## The test starts with the ENABLE_INPUTS activated and is checking if the expected |
## amount of pulses is arriving to each channel. |
## Then the ENABLE_INPUTS is deactivated and the test is checking if pulses arrive |
## to any of the channels. |
## |
## Note that the tdc_pts_inputs_fpga_enable.py is a similar test enabling and |
## disabling the ENABLE_INPUTS signal and testing for pulses on the TDC_IN_FPGA |
## lines, rather than the TDC_STOP lines that are tested in this test. |
## Note that the fpga_inputs_disable.py is a similar test enabling and disabling |
## the ENABLE_INPUTS signal and testing for pulses on the TDC_IN_FPGA lines, rather |
## than the TDC_STOP lines that are tested in this test. |
## |
## FW to load tdc_allothertests.bit |
## Authors Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
......@@ -54,23 +56,51 @@ import sys
import time
import os
import math
from numpy import *
from ctypes import *
from datetime import datetime
# Add common modules location tp path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
# Add common modules location to path
sys.path.append('../../../../pts/')
sys.path.append('../../../../pts/gnurabbit/python/')
sys.path.append('../../../../pts/common/')
sys.path.append('../../../../pts/common/usb_box')
sys.path.append('../../../../pts/common/cp210x')
# Import common modules
from ptsexcept import *
import rr
import csr
# Import specific modules
import fmc_tdc
sys.path.append('../../../common/fmc_delay/software/python/')
import fdelay_lib
from cp210x_eeprom import *
from PendulumCNT91 import *
from calibr_box import *
from find_usb_tty import *
# Pendulum
PENDULUM = "/dev/usbtmc1"
USB_DEVICE = "/dev/ttyUSB0"
RS232_BAUD = 57600
def pendulum_output_on(meas):
meas.write("OUTP:TYPE PULS")
meas.write("SOUR:PULS:PER 0.008")
meas.write("SOUR:PULS:WIDT 0.0002")
return (1)
def pendulum_output_off(meas):
meas.write("OUTP:TYPE OFF")
return (1)
# USB-interconnection-box
BOX_USB_VENDOR_ID = 0x10c4 # Cygnal Integrated Products, Inc.
BOX_USB_DEVICE_ID = 0xea60 # CP210x Composite Device
NUM_OF_TSTAMPS = 10 # number of fill-ups of the TDC memory
# ex NUM_OF_TSTAMPS = 10, means aquisition
# of 2560 timestamps; in this setup this means
# 640 rising edge timestamps per channel
##-------------------------------------------------------------------------------------------------
## Main --
......@@ -78,26 +108,26 @@ import fdelay_lib
def main (default_directory='.'):
# Constants declaration
start_test_time = time.time()
#-----> PCIe address, firmware, loader constants
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_allothertests.bit'
FMC_DELAY_ADDR = '1a39:0004/1a39:0004@0005:0000'
FMC_DELAY_BITSTREAM_PATH = '../firmwares/fmc_delay_spec.bin'
FPGA_LOADER_PATH = '../../../gnurabbit/user/fpga_loader'
FMC_TDC_CHANNEL_NB = 5
FPGA_LOADER_PATH = '../../../../pts/gnurabbit/user/fpga_loader'
#-----> FPGA initializations
# SPEC object declaration
spec = rr.Gennum()
#-----> TDC
# Bind SPEC object to FMC TDC card
print "\n-------------------------------------------------------------------"
print "----------------------------- FMC TDC -----------------------------"
print "----------------- TDC_STOP channels disable test ------------------\n"
print ("Test of EN_INPUTS signal. The test is using the Fine Delay board as\n"
print ("Test of EN_INPUTS signal. The test is using the Pendulum as\n"
"pulse generator, sending pulses to each one of the TDC channels.\n"
"The test configures the ACAM chip and then retrieves the generated timestamps.\n"
"The test configures the ACAM chip and then retrieves the generated "
"timestamps.\n"
"When the EN_INPUTS is disabled no pulse should be retrieved.\n")
print "\n_______________________________Info______________________________\n"
......@@ -113,10 +143,6 @@ def main (default_directory='.'):
bitstream = os.path.join(default_directory, FMC_TDC_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
time.sleep(1)
firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
bitstream = os.path.join(default_directory, FMC_TDC_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
time.sleep(1)
print "Firmware loaded!"
# TDC object declaration
......@@ -126,17 +152,17 @@ def main (default_directory='.'):
bitstream_type = tdc.read_bitstream_type()
if(bitstream_type == 0xFFFFFFFF):
msg = ("FATAL ERROR: No access to TDC core")
os.close(spec.fd)
print (msg)
raise PtsCritical (msg)
if(bitstream_type != 0x1):
msg = ("FATAL ERROR: Wrong bitstream type loaded")
os.close(spec.fd)
raise PtsError (msg)
if(bitstream_type != 0x2):
msg = ("FATAL ERROR: Wrong bitstream type loaded 0x%08X") %bitstream_type
print (msg)
raise PtsCritical (msg)
#raise PtsError (msg)
else:
print('Access to TDC core OK')
#-----> ACAM and TDC configuration
# Configure ACAM and TDC core registers
print "\n__________________________Configuration__________________________\n"
tdc.config_acam()
......@@ -147,9 +173,7 @@ def main (default_directory='.'):
print "ACAM IC8: Status register OK"
else:
msg = ("ERROR: ACAM IC8: No communication")
os.close(spec.fd)
print (msg)
raise PtsError (msg)
acam_readback_regs = []
acam_readback_regs = tdc.readback_acam_config()
for i in range(len(tdc.ACAM_READBACK_REGS)):
......@@ -157,131 +181,132 @@ def main (default_directory='.'):
print "ACAM IC8: reg 0x%02X: 0x%08X OK"%(tdc.ACAM_READBACK_ADDR[i], acam_readback_regs[i])
else:
msg = ("ERROR: ACAM IC8: Configuration registers failure; reg 0x%2X: received 0x%8X, expected 0x%8X"%(tdc.ACAM_READBACK_ADDR[i], acam_readback_regs[i], tdc.ACAM_READBACK_REGS[i]))
os.close(spec.fd)
print (msg)
raise PtsError (msg)
# DAC
tdc.configure_mezz_dac(0xA9CF)
# Interrupts
print "\n____________________________IRQs_________________________________\n"
print('Set IRQ enable mask: %.4X')%tdc.set_irq_en_mask(0x1F)
tdc.set_irq_tstamp_thresh(0x100)
tdc.set_irq_time_thresh(0xFFFFF)
# Enable terminations of channels 1,2,3,4,5
tdc.enable_channels()
tdc.channel_term(1, 1)
tdc.channel_term(2, 1)
tdc.channel_term(3, 1)
tdc.channel_term(4, 1)
tdc.channel_term(5, 1)
#-----> USB-interconnection-box
# Communication and setup of Interconnection box
print "\n_____________________USB interconnection box______________________\n"
box_tty = CttyUSB().find_usb_tty(BOX_USB_VENDOR_ID, BOX_USB_DEVICE_ID)
print("Device: %s" % box_tty[0])
box = CCalibr_box(box_tty[0])
box.select_trigger_loopback(0)
box.select_output(4)
#-----> Pendulum
# Communication with Pendulum
print "\n__________________________USB Pendulum_____________________________\n"
try:
meas = PendulumCNT91(PENDULUM)
except OSError:
raise PtsError('CNT-91 is not switched on or badly connected, aborting.')
a = pendulum_output_off(meas)
#-----> TDC
# Enable channels and start timestamps acquisition (TDC_START_FPGA pulse sent at this step)
print "\n______________________ACAM acquisition start________________________\n"
# Disable the 5 TDC channels
tdc.disable_channels()
for ch in range(1,FMC_TDC_CHANNEL_NB+1):
for ch in range(1,6):
tdc.channel_term(ch, 1)
# Enable timestamps aquisition (TDC_START_FPGA pulse sent at this step)
tdc.start_acq()
print ("Sending pulses of period 8 ms to each TDC STOP channel")
print "\n-----------------------------------------------------------------\n\n\n"
#-----> Fine Delay
# Bind SPEC object to FMC Fine Delay card
print "\n___________________________Fine Delay____________________________"
print "\nFine Delay initializations.."
print "Fine Delay address to parse %s"%(FMC_DELAY_ADDR)
for name, value in spec.parse_addr(FMC_DELAY_ADDR).iteritems():
print "%s:0x%04X"%(name, value)
spec.bind(FMC_DELAY_ADDR)
# Load FMC Fine Delay firmware
print "\nLoading FMC Fine Delay firmware...",
sys.stdout.flush()
firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
bitstream = os.path.join(default_directory, FMC_DELAY_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
time.sleep(1)
print "Firmware loaded!"
# Fine Delay object declaration
try:
fdelay = fdelay_lib.FineDelay(spec.get_fd())
except:
msg = ("ERROR: Fine Delay board Initiliazation failed")
os.close(spec.fd)
print (msg)
raise PtsError (msg)
# Set UTC and Coarse time in the Fine Delay
fdelay.set_time(0, 0)
fd_time = fdelay_lib.fd_timestamp()
fd_time = fdelay.get_time()
# Configure the Fine Delay as a pulse generator
enable = 1
t_start_coarse = 0
width = 100000000 # pulse width 100 ms
delta = 200000000 # rising edges every 200 ms
# string to keep the ERROR messages from all the channels
# string to keep the ERROR messages from all the channels
all_msg = ""
for i in range(4): # one iteration per channel;
# channels 4 and 5 receive pulses at the same time
time.sleep(0.5) # needed between iterations
#-----> Sending pulses to all the channels
for i in range(4): # for the 4 pairs of channels (1,2), (1,3), (1,4), (1,5)
#-----> Fine Delay
# Bind SPEC object to FMC Fine Delay card
spec.bind(FMC_DELAY_ADDR)
channel = i+1
count = 6+(2*i)
t_start_utc = fdelay.get_time().utc+1 # starting in 1 sec
fdelay.conf_pulsegen(channel, enable, t_start_utc, t_start_coarse, width, delta, count)
otherch = i+1
r_edge_timestamps_ch1 = []
r_edge_timestamps_otherch = []
all_measurs = []
#-----> TDC
# Bind SPEC object to FMC TDC card
spec.bind(FMC_TDC_ADDR)
# Check if timestamps arrived
print "\n____________________TDC_STOP%d disable test_____________________\n" %channel
time.sleep(1.5)
print "The time now is : %s" %datetime.now()
print "The temperature now is : %3.3f°C" %tdc.mezz_get_temp()
print "Fine Delay sent : %d pulses of 200ns period"%(count)
print "TDC Write pointer : %d"%(tdc.get_pointer())
timestamps, data = tdc.get_timestamps(0)
# USB-interconnection-box
box.select_trigger_loopback(0)
box.select_output(4-i)
if (i < 3):
# pendulum output on
a = pendulum_output_on(meas)
timestamp_arrived = 0
# TDC acquisition of NUM_OF_TSTAMPS*64 timestamps per channel
for j in range(NUM_OF_TSTAMPS):
time.sleep(1)
timestamps, data = tdc.get_timestamps(0)
# keep only rising edge timestamps
for m in range(len(timestamps)):
if ((timestamps[m][2] == 1) and (timestamps[m][1] == i)):
timestamp_arrived = timestamp_arrived+1
if (timestamp_arrived != 0):
msg = (("ERROR: ENABLE_INPUTS disabled: TDC_STOP%d failure; %d pulses sent, %d pulses received") %(channel, count, timestamp_arrived))
if (timestamps[m][2] == 1) and (timestamps[m][1] == 0): # rising tstamps ch1
r_edge_timestamps_ch1.append(timestamps[m][0])
elif (timestamps[m][2] == 1) and (timestamps[m][1] == otherch): # rising tstamps pair channel
r_edge_timestamps_otherch.append(timestamps[m][0])
# pendulum output off
a = pendulum_output_off(meas)
# keep only rising edge timestamps
tdc_write_pointer_now = tdc.get_pointer()
tdc_overflows_now = tdc.get_overflow_counter()
# data manipulation
if i == 0:
print "\n_________________________TDC_STOP%d test____________________________\n" %(i+1)
print "Ch1 tstamps : %d"%(len(r_edge_timestamps_ch1))
print "TDC write pointer : %d"%(tdc_write_pointer_now)
print "TDC overflows : %d"%(tdc_overflows_now)
# check if pulses arrived
if (len(r_edge_timestamps_ch1) != 0):
msg = ("ERROR: ENABLE_INPUTS disabled: TDC_STOP1 failure; %d pulses received \n")%(len(r_edge_timestamps_ch1))
print (msg)
all_msg+=msg
else:
print("Channel disabling : OK! no pulses arrived")
print("Channel disabling : OK! no pulses arrived")
else: # channels 4 and 5 are receiving timestamps at the same time
timestamp_arrived_ch4 = 0
timestamp_arrived_ch5 = 0
for m in range(len(timestamps)):
if ((timestamps[m][2] == 1) and (timestamps[m][1] == 3)):
timestamp_arrived_ch4 = timestamp_arrived_ch4+1
elif ((timestamps[m][2] == 1) and (timestamps[m][1] == 4)):
timestamp_arrived_ch5 = timestamp_arrived_ch5+1
if (timestamp_arrived_ch4 != 0):
msg = (("ERROR: ENABLE_INPUTS disabled: TDC_STOP%d failure; %d pulses sent, %d pulses received") %(channel, count, timestamp_arrived_ch4))
print (msg)
all_msg+=msg
else:
print("Channel disabling : OK! no pulses arrived")
if (timestamp_arrived_ch5 != 0):
print "\n___________________TDC_STOP5 disable test____________________\n"
msg = (("ERROR: ENABLE_INPUTS disabled: TDC_STOP5 failure; %d pulses sent, %d pulses received") %(count, timestamp_arrived_ch5))
print (msg)
all_msg+=msg
else:
print "\n___________________TDC_STOP5 disable test____________________\n"
print("Channel disabling : OK! no pulses arrived")
print "\n_________________________TDC_STOP%d test____________________________\n" %(i+2)
print "Ch%d tstamps : %d"%(i+2, len(r_edge_timestamps_otherch))
print "TDC write pointer : %d"%(tdc_write_pointer_now)
print "TDC overflows : %d"%(tdc_overflows_now)
# check if pulses arrived
if (len(r_edge_timestamps_otherch) != 0):
msg = ("ERROR: ENABLE_INPUTS disabled: TDC_STOP%d failure; %d pulses received \n")%(i+2,len(r_edge_timestamps_otherch))
print (msg)
all_msg+=msg
else:
print("Channel disabling : OK! no pulses arrived")
if (all_msg != ""):
os.close(spec.fd)
print (all_msg)
raise PtsError (all_msg)
os.close(spec.fd)
print "\n-----------------------------------------------------------------\n\n\n"
print "\n\n--------------------------------"
end_test_time = time.time()
print "Test elapsed time: %.2f seconds\n\n\n" % (end_test_time-start_test_time)
if __name__ == '__main__' :
......
......@@ -15,11 +15,12 @@
## |
## Description Testing of the TDC_START_DIS and TDC_STOP_DIS signals; when activated no |
## timestamps should be registered by the ACAM. |
## The test is using thr Fine Delay as pulse generator sending pulses to all the TDC |
## channels; if there are registered pulses one or both signals are faulty. |
## The test is using the Pendulum as pulse generator that in collaboration with the |
## Timetech Fanout and the USB-interconnection-box is sending pulses to each one of |
## the TDC channels; if there are registered pulses one or both signals are faulty. |
## |
## |
## FW to load .bin |
## FW to load tdc_allothertests.bit |
## Authors Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
## Website http://www.ohwr.org/projects/pts |
## Date 11/01/2013 |
......@@ -48,22 +49,45 @@ import sys
import time
import os
import math
from numpy import *
from ctypes import *
from datetime import datetime
# Add common modules location tp path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
# Add common modules location to path
sys.path.append('../../../../pts/')
sys.path.append('../../../../pts/gnurabbit/python/')
sys.path.append('../../../../pts/common/')
sys.path.append('../../../../pts/common/usb_box')
sys.path.append('../../../../pts/common/cp210x')
# Import common modules
from ptsexcept import *
import rr
import csr
# Import specific modules
import fmc_tdc
sys.path.append('../../../common/fmc_delay/software/python/')
import fdelay_lib
from cp210x_eeprom import *
from PendulumCNT91 import *
from calibr_box import *
from find_usb_tty import *
# Pendulum
PENDULUM = "/dev/usbtmc1"
USB_DEVICE = "/dev/ttyUSB0"
RS232_BAUD = 57600
def pendulum_output_on(meas):
meas.write("OUTP:TYPE PULS")
meas.write("SOUR:PULS:PER 0.5")
meas.write("SOUR:PULS:WIDT 0.1")
return (1)
def pendulum_output_off(meas):
meas.write("OUTP:TYPE OFF")
return (1)
# USB-interconnection-box
BOX_USB_VENDOR_ID = 0x10c4 # Cygnal Integrated Products, Inc.
BOX_USB_DEVICE_ID = 0xea60 # CP210x Composite Device
##-------------------------------------------------------------------------------------------------
......@@ -72,39 +96,41 @@ import fdelay_lib
def main (default_directory='.'):
# Constants declaration
start_test_time = time.time()
#-----> PCIe address, firmware, loader constants
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_allothertests.bit'
FMC_DELAY_ADDR = '1a39:0004/1a39:0004@0005:0000'
FMC_DELAY_BITSTREAM_PATH = '../firmwares/fmc_delay_spec.bin'
FPGA_LOADER_PATH = '../../../gnurabbit/user/fpga_loader'
FPGA_LOADER_PATH = '../../../../pts/gnurabbit/user/fpga_loader'
#-----> FPGA constants
FMC_TDC_CHANNEL_NB = 5
CARRIER_CSR = 0xC0000
ACAM_STARTDIS = 0x40
ACAM_STOPDIS = 0x44
#-----> FPGA initializations
# SPEC object declaration
spec = rr.Gennum()
#-----> TDC
# Bind SPEC object to FMC TDC card
print "\n-------------------------------------------------------------------"
print "----------------------------- FMC TDC -----------------------------"
print "------------------ TDC_START_DIS, TDC_STOP_DIS test ---------------\n"
print ("Testing of the TDC_START_DIS and TDC_STOP_DIS signals;\n"
"upon activation, no timestamps should be registered by the ACAM.\n"
"The test configures the ACAM and is using thr Fine Delay as pulse\n"
"generator sending pulses to all the TDC channels; if there are\n"
"registered pulses one or both signals are faulty.\n")
"The test configures the ACAM and is using the Pendulum as pulse\n"
"generator that in collaboration with the Timetech Fanout and the\n"
"USB-interconnection-box is sending pulses to each one of the TDC\n"
"channels; if there are registered pulses one or both signals are\n"
"faulty.\n")
print "\n_______________________________Info______________________________\n"
print "FMC TDC address to parse: %s"%(FMC_TDC_ADDR)
for name, value in spec.parse_addr(FMC_TDC_ADDR).iteritems():
print "%s:0x%04X"%(name, value)
spec.bind(FMC_TDC_ADDR)
carrier_csr = csr.CCSR(spec, CARRIER_CSR)
# Load FMC TDC firmware
print "\n_________________________Initialisations_________________________\n"
......@@ -113,10 +139,6 @@ def main (default_directory='.'):
bitstream = os.path.join(default_directory, FMC_TDC_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
time.sleep(1)
firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
bitstream = os.path.join(default_directory, FMC_TDC_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
time.sleep(1)
print "Firmware loaded!"
# TDC object declaration
......@@ -126,17 +148,17 @@ def main (default_directory='.'):
bitstream_type = tdc.read_bitstream_type()
if(bitstream_type == 0xFFFFFFFF):
msg = ("FATAL ERROR: No access to TDC core")
os.close(spec.fd)
print (msg)
raise PtsCritical (msg)
raise PtsError (msg)
if(bitstream_type != 0x1):
msg = ("FATAL ERROR: Wrong bitstream type loaded")
os.close(spec.fd)
msg = ("FATAL ERROR: Wrong bitstream type loaded 0x%08X") %bitstream_type
print (msg)
raise PtsCritical (msg)
#raise PtsError (msg)
else:
print('Access to TDC core OK')
#-----> ACAM and TDC configuration
# Configure ACAM and TDC core registers
print "\n__________________________Configuration__________________________\n"
tdc.config_acam()
......@@ -147,9 +169,7 @@ def main (default_directory='.'):
print "ACAM IC8: Status register OK"
else:
msg = ("ERROR: ACAM IC8: No communication")
os.close(spec.fd)
print (msg)
raise PtsError (msg)
acam_readback_regs = []
acam_readback_regs = tdc.readback_acam_config()
for i in range(len(tdc.ACAM_READBACK_REGS)):
......@@ -157,99 +177,102 @@ def main (default_directory='.'):
print "ACAM IC8: reg 0x%02X: 0x%08X OK"%(tdc.ACAM_READBACK_ADDR[i], acam_readback_regs[i])
else:
msg = ("ERROR: ACAM IC8: Configuration registers failure; reg 0x%2X: received 0x%8X, expected 0x%8X"%(tdc.ACAM_READBACK_ADDR[i], acam_readback_regs[i], tdc.ACAM_READBACK_REGS[i]))
os.close(spec.fd)
print (msg)
raise PtsError (msg)
# DAC
tdc.configure_mezz_dac(0xA9CF)
# Enable terminations of channels 1,2,3,4
# channels 4 and 5 are receiving the same Fine Delay pulse; only channel 5 termination activated
# Interrupts
print "\n____________________________IRQs_________________________________\n"
print('Set IRQ enable mask: %.4X')%tdc.set_irq_en_mask(0x1F)
tdc.set_irq_tstamp_thresh(0x100)
tdc.set_irq_time_thresh(0xFFFFF)
# Enable channels and terminations of all channels
tdc.enable_channels()
tdc.channel_term(1, 1)
tdc.channel_term(2, 1)
tdc.channel_term(3, 1)
tdc.channel_term(4, 1)
tdc.channel_term(5, 1)
# Enable timestamps aquisition (TDC_START_FPGA pulse sent at this step)
#-----> USB-interconnection-box
# Communication and setup of Interconnection box
print "\n_____________________USB interconnection box______________________\n"
box_tty = CttyUSB().find_usb_tty(BOX_USB_VENDOR_ID, BOX_USB_DEVICE_ID)
print("Device: %s" % box_tty[0])
box = CCalibr_box(box_tty[0])
box.select_trigger_loopback(0)
box.select_output(4)
#-----> Pendulum
# Communication with Pendulum
print "\n__________________________USB Pendulum_____________________________\n"
try:
meas = PendulumCNT91(PENDULUM)
except OSError:
raise PtsError('CNT-91 is not switched on or badly connected, aborting.')
a = pendulum_output_off(meas)
#-----> TDC
# Enable channels and start timestamps acquisition (TDC_START_FPGA pulse sent at this step)
print "\n______________________ACAM acquisition start________________________\n"
tdc.start_acq()
print ("Sending the ACAM START pulse\n")
# StartDis, StopDis
carrier_csr = csr.CCSR(spec, CARRIER_CSR)
carrier_csr.wr_reg(ACAM_STARTDIS,0x1)
carrier_csr.wr_reg(ACAM_STOPDIS,0x1)
# sending pulses to all the channels
print ("Sending pulses of period 8 ms to each TDC STOP channel")
for i in range(4): # for the 4 pairs of channels (1,2), (1,3), (1,4), (1,5)
#-----> Fine Delay
# Bind SPEC object to FMC Fine Delay card
print "\n___________________________Fine Delay____________________________"
print "\nFine Delay initializations.."
print "Fine Delay address to parse %s"%(FMC_DELAY_ADDR)
for name, value in spec.parse_addr(FMC_DELAY_ADDR).iteritems():
print "%s:0x%04X"%(name, value)
spec.bind(FMC_DELAY_ADDR)
otherch = i+1
r_edge_timestamps_ch1 = []
r_edge_timestamps_otherch = []
all_measurs = []
# Load FMC Fine Delay firmware
print "\nLoading FMC Fine Delay firmware...",
sys.stdout.flush()
firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
bitstream = os.path.join(default_directory, FMC_DELAY_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
time.sleep(1)
print "Firmware loaded!"
# USB-interconnection-box
box.select_trigger_loopback(0)
box.select_output(4-i)
# Fine Delay object declaration
try:
fdelay = fdelay_lib.FineDelay(spec.get_fd())
except:
msg = ("ERROR: Fine Delay board Initiliazation failed")
os.close(spec.fd)
print (msg)
raise PtsError (msg)
# pendulum output on
a = pendulum_output_on(meas)
# Set UTC and Coarse time in the Fine Delay
fdelay.set_time(0, 0)
fd_time = fdelay_lib.fd_timestamp()
fd_time = fdelay.get_time()
# Configure the Fine Delay as a pulse generator
enable = 1
t_start_coarse = 0
width = 100000 # pulse width 100 ns
delta = 200000 # rising edges every 200 ns
count = 6
all_measurs = []
avg = []
for i in range(4): # one iteration per channel;
# channels 4 and 5 receive pulses at the same time
#-----> Fine Delay
time.sleep(0.5) # needed between iterations
channel = i+1
t_start_utc = fdelay.get_time().utc+1 # starting in 1 sec
fdelay.conf_pulsegen(channel, enable, t_start_utc, t_start_coarse, width, delta, count)
# pendulum sending pulses
time.sleep(1.2)
# pendulum output off
a = pendulum_output_off(meas)
#-----> TDC
# Bind SPEC object to FMC TDC card
spec.bind(FMC_TDC_ADDR)
# Check if any timestamp arrived
time.sleep(1)
print "\n___________________ACAM StartDis, StopDis test___________________\n"
print "The time now is : %s" %datetime.now()
print "The temperature now is : %3.3f°C" %tdc.mezz_get_temp()
print "Fine Delay sent : 6 pulses of 200ns period to each TDC channel"
print "TDC Write pointer : %d"%(tdc.get_pointer())
if (tdc.get_pointer() == 0):
print "TDC write pointer : %d"%(tdc.get_pointer())
print "TDC overflows : %d"%(tdc.get_overflow_counter())
if (tdc.get_pointer() == 0 and tdc.get_overflow_counter() == 0):
print ("ACAM StartDis and StopDis signals : OK!")
else:
msg = (("ERROR: ACAM IC8: StartDis and/or StopDis: pulses registered, despite disabling;\n"
" in total %d pulses sent, %d timestamps registered") %(count*FMC_TDC_CHANNEL_NB,(tdc.get_pointer()/32)))
" 16 pulses sent, %d timestamps registered") %((tdc.get_pointer()/32))) # assuming get_overflow_counter=0
os.close(spec.fd)
print (msg)
raise PtsError (msg)
os.close(spec.fd)
print "\n-----------------------------------------------------------------\n\n\n"
print "\n\n--------------------------------"
end_test_time = time.time()
print "Test elapsed time: %.2f seconds\n\n\n" % (end_test_time-start_test_time)
if __name__ == '__main__' :
......
......@@ -60,27 +60,28 @@ import os
import math
# Add common modules location tp path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
sys.path.append('../../../../pts/')
sys.path.append('../../../../pts/gnurabbit/python/')
sys.path.append('../../../../pts/common/')
# Import common modules
from ptsexcept import *
import rr
import csr
# Import specific modules
import fmc_tdc
def main (default_directory='.'):
# Constants declaration
start_test_time = time.time()
#-----> PCIe address, firmware, loader constants
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_pts_clks.bit'
FPGA_LOADER_PATH = '../../../gnurabbit/user/fpga_loader'
FPGA_LOADER_PATH = '../../../../pts/gnurabbit/user/fpga_loader'
#-----> FPGA constants
# Addressing for the retrieval of carrier csr information
CARRIER_CSR = 0x00000 # base address
CSR_TYPE_VER = 0x00
......@@ -98,7 +99,9 @@ def main (default_directory='.'):
EN_COUNTERS = 0x28
CLK_31M25_COUNTER = 0x2C
CLK_125M_COUNTER = 0x3C
#-----> FPGA initializations
# SPEC object declaration
spec = rr.Gennum()
......@@ -107,8 +110,9 @@ def main (default_directory='.'):
print "----------------------------- FMC TDC -----------------------------"
print "--------------------------- Clocks test ---------------------------\n"
print ("Test of the PLL clocks: 31.25MHz FPGA_TDC_REF_CLK and 125MHz CLK125.\n"
"The test starts by configuring the PLL IC4. Then, to verify the clock\n"
"frequencies, there are dedicated counters implemented in the carrier FPGA.\n")
"The test starts by configuring the PLL IC4. Then, to verify the\n"
"clock frequencies, there are dedicated counters implemented in the\n"
"carrier FPGA.\n")
print "\n_______________________________Info______________________________\n"
print "FMC TDC address to parse: %s"%(FMC_TDC_ADDR)
......@@ -165,9 +169,9 @@ def main (default_directory='.'):
else:
print("Mezzanine present : OK")
time.sleep(3)
#-----> Check the clocks
print "\n\n___________________________PLL status____________________________\n"
pll_status = carrier_csr.rd_reg(PLL_STATUS)
if pll_status == 1:
......@@ -189,7 +193,7 @@ def main (default_directory='.'):
clk_125M = ((carrier_csr.rd_reg(CLK_125M_COUNTER))/ (2*1e6))
# FPGA_TDC_REF_CLK 31.25MHz clock evaluation
if (clk_31M25 > 32.8) or (clk_31M25 < 29.6): # 5% limits due to software inacuracies
if (clk_31M25 > 32.8) or (clk_31M25 < 29.6): # 5% limits due to software inaccuracies
msg = (("ERROR: PLL IC4: FPGA_TDC_REF_CLK: measured frequency %.2f MHz is out of accepted limits [29.6MHz..32.8MHz]") % (clk_31M25))
os.close(spec.fd)
print (msg)
......@@ -198,7 +202,7 @@ def main (default_directory='.'):
print("FPGA_TDC_REF_CLK: measured frequency: %.2f MHz OK") % (clk_31M25)
# CLK125 125MHz clock evaluation
if (clk_125M > 131) or (clk_125M < 118): # 5% limits due to software inacuracies in time measurement (time.sleep(2))
if (clk_125M > 131) or (clk_125M < 118): # 5% limits due to software inaccuracies in time measurement (time.sleep(2))
msg = (("ERROR: PLL IC4: CLK125: measured frequency %.2f MHz is out of accepted limits [118MHz..131MHz]") % (clk_125M))
os.close(spec.fd)
print (msg)
......@@ -207,8 +211,9 @@ def main (default_directory='.'):
print("CLK125: measured frequency: %.2f MHz OK") % (clk_125M)
os.close(spec.fd)
print "\n\n-----------------------------------------------------------------"
print "\n\n--------------------------------"
end_test_time = time.time()
print "Test elapsed time: %.2f seconds\n\n\n" % (end_test_time-start_test_time)
if __name__ == '__main__' :
main()
......@@ -13,14 +13,15 @@
## |
##-------------------------------------------------------------------------------------------------
## |
## Description Testing of the DAC IC2. The test is using the Fine Delay board as pulse generator,|
## Description Testing of the DAC IC2. The test is using the Pendulum as pulse generator, sending|
## sending 1 Hz pulses to TDC channel 1. The firmware loaded on the carrier FPGA |
## configures the ACAM; it also configures the DAC through its SPI interface. |
## Two values are set in the DAC: first, a low one (0V) and then a higher one (1.6V).|
## The ACAM timestamps are retrieved and evaluated: the pulse duration is expected |
## to be higher when the DAC value is high and lower when the DAC value is low. |
## |
## FW to load .bin |
## |
### FW to load tdc_allothertests.bit |
## Authors Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
## Website http://www.ohwr.org/projects/pts |
## Date 11/01/2013 |
......@@ -43,30 +44,56 @@
## Import --
##-------------------------------------------------------------------------------------------------
# Import system modules
import sys
import time
import os
import math
from numpy import *
from ctypes import *
from datetime import datetime
# Add common modules location tp path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
# Add common modules location to path
sys.path.append('../../../../pts/')
sys.path.append('../../../../pts/gnurabbit/python/')
sys.path.append('../../../../pts/common/')
sys.path.append('../../../../pts/common/usb_box')
sys.path.append('../../../../pts/common/cp210x')
# Import common modules
from ptsexcept import *
import rr
import csr
# Import specific modules
import fmc_tdc
sys.path.append('../../../common/fmc_delay/software/python/')
import fdelay_lib
from cp210x_eeprom import *
from PendulumCNT91 import *
from calibr_box import *
from find_usb_tty import *
# Pendulum
PENDULUM = "/dev/usbtmc1"
USB_DEVICE = "/dev/ttyUSB0"
RS232_BAUD = 57600
def pendulum_output_on(meas):
meas.write("OUTP:TYPE PULS")
meas.write("SOUR:PULS:PER 0.008")
meas.write("SOUR:PULS:WIDT 0.0002")
return (1)
def pendulum_output_off(meas):
meas.write("OUTP:TYPE OFF")
return (1)
# USB-interconnection-box
BOX_USB_VENDOR_ID = 0x10c4 # Cygnal Integrated Products, Inc.
BOX_USB_DEVICE_ID = 0xea60 # CP210x Composite Device
NUM_OF_TSTAMPS = 10 # number of fill-ups of the TDC memory
# ex NUM_OF_TSTAMPS = 10, means aquisition
# of 2560 timestamps; in this setup this means
# 640 rising edge timestamps per channel
##-------------------------------------------------------------------------------------------------
## Main --
......@@ -74,29 +101,28 @@ import fdelay_lib
def main (default_directory='.'):
# Constants declaration
start_test_time = time.time()
#-----> PCIe address, firmware, loader constants
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_allothertests.bit'
FMC_DELAY_ADDR = '1a39:0004/1a39:0004@0005:0000'
FMC_DELAY_BITSTREAM_PATH = '../firmwares/fmc_delay_spec.bin'
FPGA_LOADER_PATH = '../../../gnurabbit/user/fpga_loader'
FMC_TDC_CHANNEL_NB = 5
FPGA_LOADER_PATH = '../../../../pts/gnurabbit/user/fpga_loader'
#-----> FPGA initializations
# SPEC object declaration
spec = rr.Gennum()
#-----> TDC
# Bind SPEC object to FMC TDC card
print "\n-------------------------------------------------------------------"
print "----------------------------- FMC TDC -----------------------------"
print "---------------------------- DAC test -----------------------------\n"
print ("Testing of the DAC IC2. The test is using the Fine Delay board as pulse\n"
"generator, sending 1 Hz pulses to TDC channel 1. The test configures the\n"
"ACAM and then the DAC through its SPI interface. Two values are set in the\n"
"DAC: first, a low one (0V) and then a higher one (1.6V). The ACAM timestamps\n"
"are retrieved and evaluated: the pulse duration is expected to be higher\n"
"when the DAC value is high and lower when the DAC value is low.\n")
print ("Testing of the DAC IC2. The test is using the Pendulum as pulse\n"
"generator, sending 1 Hz pulses to TDC channel 1. The test configures\n"
"the ACAM and then the DAC through its SPI interface. Two values are\n"
"set in the DAC: first, a low one (0V) and then a higher one (1.6V).\n"
"The ACAM timestamps are retrieved and evaluated: the pulse duration\n"
"is expected to be higher when the DAC value is high and lower when\n"
"the DAC value is low.\n")
print "\n_______________________________Info______________________________\n"
print "FMC TDC address to parse: %s"%(FMC_TDC_ADDR)
......@@ -111,10 +137,6 @@ def main (default_directory='.'):
bitstream = os.path.join(default_directory, FMC_TDC_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
time.sleep(1)
firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
bitstream = os.path.join(default_directory, FMC_TDC_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
time.sleep(1)
print "Firmware loaded!"
# TDC object declaration
......@@ -124,17 +146,17 @@ def main (default_directory='.'):
bitstream_type = tdc.read_bitstream_type()
if(bitstream_type == 0xFFFFFFFF):
msg = ("FATAL ERROR: No access to TDC core")
os.close(spec.fd)
print (msg)
raise PtsCritical (msg)
raise PtsError (msg)
if(bitstream_type != 0x1):
msg = ("FATAL ERROR: Wrong bitstream type loaded")
os.close(spec.fd)
msg = ("FATAL ERROR: Wrong bitstream type loaded 0x%08X") %bitstream_type
print (msg)
raise PtsCritical (msg)
raise PtsError (msg)
else:
print('Access to TDC core OK')
#-----> ACAM and TDC configuration
# Configure ACAM and TDC core registers
print "\n__________________________Configuration__________________________\n"
tdc.config_acam()
......@@ -145,9 +167,7 @@ def main (default_directory='.'):
print "ACAM IC8: Status register OK"
else:
msg = ("ERROR: ACAM IC8: No communication")
os.close(spec.fd)
print (msg)
raise PtsError (msg)
acam_readback_regs = []
acam_readback_regs = tdc.readback_acam_config()
for i in range(len(tdc.ACAM_READBACK_REGS)):
......@@ -155,139 +175,189 @@ def main (default_directory='.'):
print "ACAM IC8: reg 0x%02X: 0x%08X OK"%(tdc.ACAM_READBACK_ADDR[i], acam_readback_regs[i])
else:
msg = ("ERROR: ACAM IC8: Configuration registers failure; reg 0x%2X: received 0x%8X, expected 0x%8X"%(tdc.ACAM_READBACK_ADDR[i], acam_readback_regs[i], tdc.ACAM_READBACK_REGS[i]))
os.close(spec.fd)
print (msg)
raise PtsError (msg)
# Enable termination of channel 1
# DAC
tdc.configure_mezz_dac(0xA9CF)
# Interrupts
print "\n____________________________IRQs_________________________________\n"
print('Set IRQ enable mask: %.4X')%tdc.set_irq_en_mask(0x1F)
tdc.set_irq_tstamp_thresh(0x100)
tdc.set_irq_time_thresh(0xFFFFF)
# Enable channels and terminations of all channels
tdc.enable_channels()
tdc.channel_term(1, 1)
tdc.channel_term(2, 1)
tdc.channel_term(3, 1)
tdc.channel_term(4, 1)
tdc.channel_term(5, 1)
# Enable timestamps aquisition (TDC_START_FPGA pulse sent at this step)
tdc.start_acq()
#-----> USB-interconnection-box
# Communication and Setup of Interconnection box
print "\n_____________________USB interconnection box______________________\n"
box_tty = CttyUSB().find_usb_tty(BOX_USB_VENDOR_ID, BOX_USB_DEVICE_ID)
print("Device: %s" % box_tty[0])
box = CCalibr_box(box_tty[0])
box.select_trigger_loopback(0)
box.select_output(4)
#-----> Fine Delay
# Bind SPEC object to FMC Fine Delay card
print "\n___________________________Fine Delay____________________________"
print "\nFine Delay initializations.."
print "Fine Delay address to parse %s"%(FMC_DELAY_ADDR)
for name, value in spec.parse_addr(FMC_DELAY_ADDR).iteritems():
print "%s:0x%04X"%(name, value)
spec.bind(FMC_DELAY_ADDR)
# Load FMC Fine Delay firmware
print "\nLoading FMC Fine Delay firmware...",
sys.stdout.flush()
firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
bitstream = os.path.join(default_directory, FMC_DELAY_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
time.sleep(1)
print "Firmware loaded!"
# Fine Delay object declaration
#-----> Pendulum
# Communication with Pendulum
print "\n__________________________USB Pendulum_____________________________\n"
try:
fdelay = fdelay_lib.FineDelay(spec.get_fd())
except:
msg = ("ERROR: Fine Delay board Initiliazation failed")
os.close(spec.fd)
meas = PendulumCNT91(PENDULUM)
except OSError:
raise PtsError('CNT-91 is not switched on or badly connected, aborting.')
a = pendulum_output_off(meas)
# dummy sequence, coz it has been noted that otherwise few pulses of the
# configuration of test10 are being sent before switching to the new configuration
a = pendulum_output_on(meas)
time.sleep(0.2)
a = pendulum_output_off(meas)
#-----> TDC
# Enable channels and start timestamps acquisition (TDC_START_FPGA pulse sent at this step)
print "\n______________________ACAM acquisition start________________________\n"
tdc.start_acq()
print ("Sending pulses of period 8 ms to the TDC_STOP1 channel")
#-----> ############## DAC: 0x0000 ##############
print "\n____________________DAC 0x0000: 0V test______________________\n"
tdc.configure_mezz_dac(0x0)
r_edge_timestamps_ch1 = []
all_measurs = []
# pendulum output on
a = pendulum_output_on(meas)
# TDC aquisition of NUM_OF_TSTAMPS*64 timestamps per channel
for j in range(NUM_OF_TSTAMPS):
tdc.check_irq(0)
timestamps, data = tdc.get_timestamps(0)
# keep only rising edge timestamps
for m in range(len(timestamps)):
if (timestamps[m][2] == 1) and (timestamps[m][1] == 0): # rising tstamps ch1
r_edge_timestamps_ch1.append(timestamps[m][0])
# clear interrupt
tdc.clear_irq_src(int(math.log(tdc.get_irq_src(),2)))
# pendulum output off
a = pendulum_output_off(meas)
# keep only rising edge timestamps
tdc_write_pointer_now = tdc.get_pointer()
tdc_overflows_now = tdc.get_overflow_counter()
if tdc_overflows_now != NUM_OF_TSTAMPS:
msg = ("ERROR: Unexpected error with interrupts; expected overflows: %d; received overflows: %d")%((NUM_OF_TSTAMPS*(i+1)),tdc_overflows_now)
print (msg)
raise PtsError (msg)
# Set UTC and Coarse time in the Fine Delay
fdelay.set_time(0, 0)
fd_time = fdelay_lib.fd_timestamp()
fd_time = fdelay.get_time()
print "Ch1 tstamps : %d"%(len(r_edge_timestamps_ch1))
print "TDC write pointer: %d"%(tdc_write_pointer_now)
print "TDC overflows : %d"%(tdc_overflows_now)
measurs_ch1 = []
# check number of pulses arrived
if (len(r_edge_timestamps_ch1) > 63*NUM_OF_TSTAMPS) or (len(r_edge_timestamps_ch1) < 60*NUM_OF_TSTAMPS):
r_edge_timestamps_ch1.sort()
# analyse the timestamps for Ch1
for k in range(0, len(r_edge_timestamps_ch1)-1, 1):
measur = r_edge_timestamps_ch1[k+1] - r_edge_timestamps_ch1[k]
if (measur < 8999995000) or (measur < 9000005000):
measurs_ch1.append (measur)
print "samples : %d"%(len(measurs_ch1))
# evaluate the timestamps for Ch1
if (len(measurs_ch1) < 600) or (len(measurs_ch1) > 650):
msg = ("ERROR: Ch1 received %d timestamps of 8ms period; expected: around %d \n")%(len(measurs_ch1), 64*NUM_OF_TSTAMPS)
print (msg)
raise PtsError (msg)
else:
avg_0x0000 = ((sum(measurs_ch1, 0.0) / len(measurs_ch1)))
print "span : %.2f ps"%((max(measurs_ch1))-(min(measurs_ch1)))
print "average : %.2f ms"%(avg_0x0000)
print "max iter %d %.2f ps"%(measurs_ch1.index(max(measurs_ch1)), (max(measurs_ch1)))
print "min iter %d %.2f ps"%(measurs_ch1.index(min(measurs_ch1)), (min(measurs_ch1)))
else:
msg = ("ERROR: Ch1 registered timestamps: %d; expected: around %d \n")%(len(r_edge_timestamps_ch1), 64*NUM_OF_TSTAMPS)
print (msg)
raise PtsError (msg)
# Configure the Fine Delay as a pulse generator
channel = 1
enable = 1
t_start_coarse = 0
width = 100000 # pulse width 100 ns
delta = 100000000000 # rising edges every 1 sec
count = 6
one_sec_measur_list_0x0000 = []
one_sec_measur_list_0xAA57 = []
#-----> ############## DAC: 0xAA57 ##############
print "\n____________________DAC 0xAA57: 0V test______________________\n"
tdc.configure_mezz_dac(0xAA57)
for m in range(2): # 2 iterations; one with DAC at 0x0000, one with DAC 0xAA57
r_edge_timestamps_ch1 = []
all_measurs = []
time.sleep(0.5) # somehow needed
# pendulum output on
a = pendulum_output_on(meas)
#-----> Fine Delay
# Bind SPEC object to FMC Fine Delay card
spec.bind(FMC_DELAY_ADDR)
# TDC acquisition of NUM_OF_TSTAMPS*64 timestamps per channel
for j in range(NUM_OF_TSTAMPS):
tdc.check_irq(0)
timestamps, data = tdc.get_timestamps(0)
# keep only rising edge timestamps
for m in range(len(timestamps)):
if (timestamps[m][2] == 1) and (timestamps[m][1] == 0): # rising tstamps ch1
r_edge_timestamps_ch1.append(timestamps[m][0])
# clear interrupt
tdc.clear_irq_src(int(math.log(tdc.get_irq_src(),2)))
t_start_utc = fdelay.get_time().utc+1 # starting in 1 sec
fdelay.conf_pulsegen(channel, enable, t_start_utc, t_start_coarse, width, delta, count)
# pendulum output off
a = pendulum_output_off(meas)
#-----> TDC
# Bind SPEC object to FMC TDC card
spec.bind(FMC_TDC_ADDR)
# data manipulation
# Configuring DAC
if m == 0:
print "\n____________________DAC 0x0000: 0V test______________________\n"
tdc.configure_mezz_dac(0x0)
else:
print "\n____________________DAC 0xAA57: 1.6V test____________________\n"
tdc.configure_mezz_dac(0xAA57)
time.sleep(7)
print "The time now is : %s" %datetime.now()
print "The temperature now is : %3.3f°C" %tdc.mezz_get_temp()
print "Fine Delay sent : %d pulses of 1s period to TDC channel 1"%(count)
print "TDC Write pointer : %d"%(tdc.get_pointer())
# keep only rising edge timestamps
tdc_write_pointer_now = tdc.get_pointer()
tdc_overflows_now = tdc.get_overflow_counter()
if tdc_overflows_now != NUM_OF_TSTAMPS*2:
msg = ("ERROR: Unexpected error with interrupts; expected overflows: %d; received overflows: %d")%((NUM_OF_TSTAMPS*(i+1)),tdc_overflows_now)
print (msg)
raise PtsError (msg)
if (tdc.get_pointer()) == 0:
msg = ("ERROR: TDC_IN_FPGA1: No pulse arrived")
os.close(spec.fd)
print "Ch1 tstamps : %d"%(len(r_edge_timestamps_ch1))
print "TDC write pointer: %d"%(tdc_write_pointer_now)
print "TDC overflows : %d"%(tdc_overflows_now)
measurs_ch1 = []
# check number of pulses arrived
if (len(r_edge_timestamps_ch1) > 63*NUM_OF_TSTAMPS) or (len(r_edge_timestamps_ch1) < 60*NUM_OF_TSTAMPS):
r_edge_timestamps_ch1.sort()
# analyse the timestamps for Ch1
for k in range(0, len(r_edge_timestamps_ch1)-1, 1):
measur = r_edge_timestamps_ch1[k+1] - r_edge_timestamps_ch1[k]
if (measur < 8999995000) or (measur < 9000005000):
measurs_ch1.append (measur)
print "samples : %d"%(len(measurs_ch1))
# evaluate the timestamps for Ch1
if (len(measurs_ch1) < 600) or (len(measurs_ch1) > 650):
msg = ("ERROR: Ch1 received %d timestamps of 8ms period; expected: around %d \n")%(len(measurs_ch1), 64*NUM_OF_TSTAMPS)
print (msg)
raise PtsError (msg)
else:
timestamps, data = tdc.get_timestamps(0)
# keep rising edge timestamps
r_edge_timestamps = []
for i in range(len(timestamps)):
if ((timestamps[i][2] == 1)):
r_edge_timestamps.append(timestamps[i][0])
r_edge_lgth = len(r_edge_timestamps)
print "Number of rising edge timestamps : %d"%(r_edge_lgth)
if m == 0:
if (r_edge_lgth) != 6:
msg = (("ERROR: TDC_IN_FPGA1: %d pulses arrived; 6 were expected") %(r_edge_lgth))
os.close(spec.fd)
print (msg)
raise PtsError (msg)
for k in range(0,len(r_edge_timestamps),2):
one_sec_measur_0x0000 = r_edge_timestamps[k+1] - r_edge_timestamps[k]
one_sec_measur_list_0x0000.append(one_sec_measur_0x0000)
avg_dac_0x0000 = (sum(one_sec_measur_list_0x0000, 0.0) / len(one_sec_measur_list_0x0000))
print "\nDAC 0x0000: One second measurement: %.2f ps"%avg_dac_0x0000
else:
if (r_edge_lgth) != 12:
msg = (("ERROR: TDC_IN_FPGA1: %d pulses arrived; 6 were expected") %(r_edge_lgth))
os.close(spec.fd)
print (msg)
raise PtsError (msg)
for k in range(6,len(r_edge_timestamps),2):
one_sec_measur_0xAA57 = r_edge_timestamps[k+1] - r_edge_timestamps[k]
one_sec_measur_list_0xAA57.append(one_sec_measur_0xAA57)
avg_dac_0xAA57 = (sum(one_sec_measur_list_0xAA57, 0.0) / len(one_sec_measur_list_0xAA57))
print "\nDAC 0xAA57: One second measurement: %.2f ps"%avg_dac_0xAA57
print "span : %.2f ps"%((max(measurs_ch1))-(min(measurs_ch1)))
avg_0xaa57 = ((sum(measurs_ch1, 0.0) / len(measurs_ch1)))
print "average : %.2f ms"%(avg_0xaa57)
print "max iter %d %.2f ps"%(measurs_ch1.index(max(measurs_ch1)), (max(measurs_ch1)))
print "min iter %d %.2f ps"%(measurs_ch1.index(min(measurs_ch1)), (min(measurs_ch1)))
else:
msg = ("ERROR: Ch1 registered timestamps: %d; expected: around %d \n")%(len(r_edge_timestamps_ch1), 64*NUM_OF_TSTAMPS)
print (msg)
raise PtsError (msg)
print "\n_______________________DAC Test Result_______________________\n"
if (avg_dac_0xAA57 > avg_dac_0x0000 + 1000000):
if (avg_0xaa57 > avg_0x0000 + 100000):
print("DAC test OK!")
else:
msg = ("ERROR: DAC IC14: Changes in DAC are not affecting the clocks")
......@@ -295,9 +365,10 @@ def main (default_directory='.'):
print (msg)
raise PtsError (msg)
tdc.stop_acq()
os.close(spec.fd)
print "\n-----------------------------------------------------------------\n\n\n"
print "\n\n--------------------------------"
end_test_time = time.time()
print "Test elapsed time: %.2f seconds\n\n\n" % (end_test_time-start_test_time)
if __name__ == '__main__' :
......
......@@ -23,7 +23,7 @@
## |
## The test attempts several writings and readbacks on different EEPROM locations. |
## |
## FW to load .bin |
## FW to load tdc_allothertests.bit |
## Authors Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
## Website http://www.ohwr.org/projects/pts |
## Date 11/01/2013 |
......@@ -51,30 +51,36 @@ import sys
import time
import os
# Add common modules location tp path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
# Add common modules location to path
sys.path.append('../../../../pts/')
sys.path.append('../../../../pts/gnurabbit/python/')
sys.path.append('../../../../pts/common/')
# Import common modules
from ptsexcept import *
import rr
# Import specific modules
import fmc_tdc
##-------------------------------------------------------------------------------------------------
## main --
##-------------------------------------------------------------------------------------------------
def main (default_directory='.'):
start_test_time = time.time()
#-----> PCIe address, firmware, loader constants
# Constants declaration
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_allothertests.bit'#tdc_counters.bit'
FPGA_LOADER_PATH = '../../../gnurabbit/user/fpga_loader'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_allothertests.bit'
FPGA_LOADER_PATH = '../../../../pts/gnurabbit/user/fpga_loader'
#-----> EEPROM chip constant
EEPROM_ADDR = 0x50
#-----> FPGA initializations
# SPEC object declaration
spec = rr.Gennum()
......@@ -92,7 +98,7 @@ def main (default_directory='.'):
# Load FMC TDC firmware
print "\n_________________________Initialisations_________________________\n"
print "Loading FMC Fine Delay firmware...",
print "Loading FMC TDC firmware...",
firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
bitstream = os.path.join(default_directory, FMC_TDC_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
......@@ -121,6 +127,8 @@ def main (default_directory='.'):
else:
print('Access to TDC core OK')
#-----> Accessing the mezzanine EEPROM chip
print "\n__________________________EEPROM IC10 test_______________________\n"
# Scan FMC I2C bus
try:
......@@ -170,8 +178,10 @@ def main (default_directory='.'):
else:
print('\nEEPROM IC5: Data comparison OK')
os.close(spec.fd)
print "\n\n-----------------------------------------------------------------"
print "\n\n--------------------------------"
end_test_time = time.time()
print "Test elapsed time: %.2f seconds\n\n\n" % (end_test_time-start_test_time)
if __name__ == '__main__' :
main()
......@@ -16,13 +16,13 @@
## Description Testing of the presence of the TDC board on the SPEC carrier. |
## |
## The test retrieves information on the carrier board: pcb version, carrier type, |
## status, control, mezzzanine presence. |
## status, control, mezzanine presence. |
## Note that the mezzanine presence flag comes from the FMC pin prsnt_m2c_n_i. |
## |
## The WISHBONE master can be accessed at PCIe base address xC0000. |
## |
## |
## FW to load .bin |
## FW to load tdc_pts_presence.bit |
## Authors Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
## Website http://www.ohwr.org/projects/pts |
## Date 11/01/2013 |
......@@ -52,26 +52,27 @@ import time
import os
# Add common modules location tp path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
sys.path.append('../../../../pts/')
sys.path.append('../../../../pts/gnurabbit/python/')
sys.path.append('../../../../pts/common/')
# Import common modules
from ptsexcept import *
import rr
import csr
# Import specific modules
import fmc_tdc
def main (default_directory='.'):
# Constants declaration
start_test_time = time.time()
#-----> PCIe address, firmware, loader constants
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_pts_presence.bit'#top_tdc.bit'
FPGA_LOADER_PATH = '../../../gnurabbit/user/fpga_loader'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_pts_presence.bit'
FPGA_LOADER_PATH = '../../../../pts/gnurabbit/user/fpga_loader'
#-----> FPGA constants
# Addressing for the retrieval of carrier csr information
CARRIER_CSR = 0x00000 # base address
CSR_TYPE_VER = 0x00
......@@ -82,14 +83,16 @@ def main (default_directory='.'):
PCB_VER_MASK = 0x000F
CARRIER_TYPE_MASK = 0xFFFF0000
STATUS_FMC_PRES = (1<<0)
#-----> FPGA initializations
# SPEC object declaration
spec = rr.Gennum()
# Bind SPEC object to FMC TDC card
print "\n-------------------------------------------------------------------"
print "---------------------------- FMC TDC ---------------------------- "
print "-------------------- Mezzanine presence test --------------------\n"
print "----------------------------- FMC TDC ----------------------------- "
print "--------------------- Mezzanine presence test ---------------------\n"
print ("Test of the presence of the mezzanine, on the SPEC carrier.\n")
print "\n_______________________________Info______________________________\n"
......@@ -113,7 +116,7 @@ def main (default_directory='.'):
# Check bitsteam type
bitstream_type = carrier_csr.rd_reg(CSR_BSTM_TYPE)
print('Bitstream type :%.8X') % bitstream_type
print('Bitstream type : %.8X') % bitstream_type
if(bitstream_type == 0xFFFFFFFF):
msg = ("FATAL ERROR: Wrong bitstream type loaded")
os.close(spec.fd)
......@@ -148,8 +151,10 @@ def main (default_directory='.'):
else:
print("Mezzanine present OK\n")
os.close(spec.fd)
print "\n\n-----------------------------------------------------------------"
print "\n\n--------------------------------"
end_test_time = time.time()
print "Test elapsed time: %.2f seconds\n\n\n" % (end_test_time-start_test_time)
if __name__ == '__main__' :
main()
......@@ -60,7 +60,7 @@ class CFMCTDC:
# ACAM register addresses and expected register contents
ACAM_READBACK_ADDR = [0x40, 0x44, 0x48, 0x4C, 0X50, 0x54, 0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C, 0x70, 0x78]
ACAM_READBACK_REGS = [0xC1F0FC81, 0xC0000000, 0xC0000E02, 0xC0000000, 0xC200000F, 0xC00007D0, 0xC00000FC, 0xC0001FEA, 0x00000000, 0x00000000, 0x00000000, 0xC3000000, 0xC4000800, 0xC0000000]
ACAM_READBACK_REGS = [0xC1F0FC81, 0xC0000000, 0xC0000E02, 0xC0000000, 0xC200000F, 0xC00007D0, 0xC00000FC, 0xC0001FEA, 0x00000000, 0x00000000, 0x00000000, 0xC01F0000, 0xC4000800, 0xC0000000]
# DMA length in bytes
DMA_LENGTH = 4096
......@@ -175,8 +175,8 @@ class CFMCTDC:
self.tdc_regs.wr_reg(0x14, 0x7D0)
self.tdc_regs.wr_reg(0x18, 0x3)
self.tdc_regs.wr_reg(0x1C, 0x1FEA)
#self.tdc_regs.wr_reg(0x2C, 0xFF0000)
self.tdc_regs.wr_reg(0x2C, 0x03000000)
self.tdc_regs.wr_reg(0x2C, 0x1F0000)
#self.tdc_regs.wr_reg(0x2C, 0x03000000)
self.tdc_regs.wr_reg(0x30, 0x4000000)
self.tdc_regs.wr_reg(0x38, 0x0)
self.tdc_regs.wr_reg(0xFC, 0x4)
......
#! /usr/bin/env python
# coding: utf8
# Copyright CERN, 2011
# Author: Matthieu Cattin <matthieu.cattin@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Import system modules
import sys
import time
import os
import math
# Import common modules
import rr
from ptsexcept import *
import csr
import gn4124
import i2c
import onewire
import ds18b20
import eeprom_24aa64
# Add common modules location tp path
sys.path.append('../../../../')
sys.path.append('../../../../gnurabbit/python/')
sys.path.append('../../../../common/')
"""
FMC TDC class
"""
class CFMCTDC:
# DMA WISHBONE adress
GNUM_CSR_ADDR = 0x04000
# Carrier One Wire
CARR_ONEWIRE_ADDR = 0x04800
# Carrier CSR info
CARRIER_CSR_ADDR = 0x04C00
CSR_BSTM_TYPE = 0x04
# TDC core WISHBONE adress
TDC_CORE_ADDR = 0x05000
# IRQ controller
IRQ_CONTROLLER_ADDR = 0x05400
IRQ_CTRL_SRC = 0x04
IRQ_CTRL_EN_MASK = 0x08
# Mezzanine I2C
MEZZ_I2C_ADDR = 0x05800
MEZZ_EEPROM_ADDR = 0x50
# Mezzanine One Wire
MEZZ_ONEWIRE_ADDR = 0x05C00
# ACAM register addresses and expected register contents
ACAM_READBACK_ADDR = [0x40, 0x44, 0x48, 0x4C, 0X50, 0x54, 0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C, 0x70, 0x78]
ACAM_READBACK_REGS = [0xC1F0FC81, 0xC0000000, 0xC0000E02, 0xC0000000, 0xC200000F, 0xC00007D0, 0xC00000FC, 0xC0001FEA, 0x00000000, 0x00000000, 0x00000000, 0xC3000000, 0xC4000800, 0xC0000000]
# DMA length in bytes
DMA_LENGTH = 4096
# Write pointer register
WP_MASK = 0xFFF
WP_OVERFLOW_MASK = 0xFFFFF000
# Timestamp meta-data
META_CHANNEL_MASK = 0x07 #0xF
META_SLOPE_MASK = 0x10 #0xF0
META_FIFO_LF_MASK = 0xF00
META_FIFO_EF_MASK = 0xF000
META_SLOPE = ['falling', 'rising']
###############################################################################################
def __init__(self, bus):
# Objects delcaration
self.bus = bus;
self.gnum = gn4124.CGN4124(self.bus, self.GNUM_CSR_ADDR)
self.tdc_regs = csr.CCSR(self.bus, self.TDC_CORE_ADDR)
self.irq_controller = csr.CCSR(self.bus, self.IRQ_CONTROLLER_ADDR)
self.carrier_csr = csr.CCSR(self.bus, self.CARRIER_CSR_ADDR)
# Set GNUM local bus frequency
self.gnum.set_local_bus_freq(160)
print "Gennum local bus clock %d MHz"%(self.gnum.get_local_bus_freq())
time.sleep(2)
# Reset FPGA
print "Resetting FPGA"
self.gnum.rstout33_cycle()
time.sleep(3)
# I2C mezzanine
self.mezz_i2c = i2c.COpenCoresI2C(self.bus, self.MEZZ_I2C_ADDR, 249)
self.mezz_eeprom_24aa64 = eeprom_24aa64.C24AA64(self.mezz_i2c, self.MEZZ_EEPROM_ADDR)
# One Wire mezzanine
self.mezz_onewire = onewire.COpenCoresOneWire(self.bus, self.MEZZ_ONEWIRE_ADDR, 624, 124)
self.mezz_ds18b20 = ds18b20.CDS18B20(self.mezz_onewire, 0)
# One Wire carrier
self.carr_onewire = onewire.COpenCoresOneWire(self.bus, self.CARR_ONEWIRE_ADDR, 624, 124)
self.carr_ds18b20 = ds18b20.CDS18B20(self.carr_onewire, 0)
# Get physical addresses of the memory pages for DMA transfer
self.dma_pages = self.gnum.get_physical_addr()
###############################################################################################
# Read bitstream type
def read_bitstream_type(self):
return self.carrier_csr.rd_reg(0x04)
# Returns mezzanine unique ID
def mezz_get_unique_id(self):
return self.mezz_ds18b20.read_serial_number()
# Returns mezzanine temperature
def mezz_get_temp(self):
serial_number = self.mezz_ds18b20.read_serial_number()
if(serial_number == -1):
return -1
else:
return self.mezz_ds18b20.read_temp(serial_number)
# Returns carrier unique ID
def carr_get_unique_id(self):
return self.carr_ds18b20.read_serial_number()
# Returns carrier temperature
def carr_get_temp(self):
serial_number = self.carr_ds18b20.read_serial_number()
if(serial_number == -1):
return -1
else:
return self.carr_ds18b20.read_temp(serial_number)
# scan FMC i2c bus
def mezz_i2c_scan(self):
print 'Scanning I2C bus...',
return self.mezz_i2c.scan()
# write to EEPROM on system i2c bus
def mezz_i2c_eeprom_write(self, addr, data):
return self.mezz_eeprom_24aa64.wr_data(addr, data)
# read from EEPROM on system i2c bus
def mezz_i2c_eeprom_read(self, addr, size):
return self.mezz_eeprom_24aa64.rd_data(addr, size)
# write to EEPROM on system i2c bus
def mezz_i2c_eeprom_write_page(self, data):
byte_to_write = len(data)
addr = 0
while byte_to_write:
if byte_to_write > 32:
size = 32
else:
size = byte_to_write
self.mezz_eeprom_24aa64.wr_page(addr,data[addr:(addr+size)])
byte_to_write -= size
addr += size
time.sleep(0.005) # have to wait between writes otherwise the eeprom gives NACK on the i2c bus
# read from EEPROM on system i2c bus
def mezz_i2c_eeprom_read_chunk(self, addr, size):
return self.mezz_eeprom_24aa64.rd_seq(addr, size)
# Configures ACAM
def config_acam(self):
print "Loading ACAM and TDC core registers"
time.sleep(1)
self.tdc_regs.wr_reg(0x00, 0x1F0FC81)
self.tdc_regs.wr_reg(0x04, 0x0)
self.tdc_regs.wr_reg(0x08, 0xE02)
time.sleep(1)
self.tdc_regs.wr_reg(0x0C, 0x0)
self.tdc_regs.wr_reg(0x10, 0x200000F)
self.tdc_regs.wr_reg(0x14, 0x7D0)
self.tdc_regs.wr_reg(0x18, 0x3)
self.tdc_regs.wr_reg(0x1C, 0x1FEA)
#self.tdc_regs.wr_reg(0x2C, 0xFF0000)
self.tdc_regs.wr_reg(0x2C, 0x03000000)
self.tdc_regs.wr_reg(0x30, 0x4000000)
self.tdc_regs.wr_reg(0x38, 0x0)
self.tdc_regs.wr_reg(0xFC, 0x4)
time.sleep(1)
def load_acam_config(self):
print "Loading ACAM configuration"
self.tdc_regs.wr_reg(0xFC, 0x4)
time.sleep(1)
def reset_acam(self):
print "Reseting ACAM"
self.tdc_regs.wr_reg(0xFC, 0x100)
time.sleep(1)
# Configures DAC and PLL
def configure_mezz_dac(self, dac_word):
print "\nConfiguring mezzanine DAC 0x%4X"%dac_word
self.tdc_regs.wr_reg(0x98, dac_word) # default: xA8F5, max: xFFFF, min: x0000
self.tdc_regs.wr_reg(0xFC, 0x800)
time.sleep(2)
# def readback_acam_config(self):
# self.tdc_regs.wr_reg(0xFC, 0x8)
# time.sleep(1)
# acam_regs = []
# for i in range(len(self.ACAM_READBACK_REGS)):
# acam_regs.append (self.tdc_regs.rd_reg(i))
# if (self.tdc_regs.rd_reg(i) == self.ACAM_READBACK_REGS[i]):
# print "ACAM IC8: reg 0x%02X: 0x%08X OK"%(i, self.tdc_regs.rd_reg(i))
# else:
# print "ERROR! ACAM IC8: reg 0x%02X: received 0x%08X; expected 0x%08X"%(i, self.tdc_regs.rd_reg(i), self.ACAM_READBACK_REGS[i])
# return acam_regs
def readback_acam_config(self):
self.tdc_regs.wr_reg(0xFC, 0x8)
time.sleep(1)
acam_regs = []
for i in self.ACAM_READBACK_ADDR:
acam_regs.append (self.tdc_regs.rd_reg(i))
#print "ACAM IC8: reg 0x%02X: 0x%08X OK"%(i, self.tdc_regs.rd_reg(i))
return acam_regs
# Read ACAM status register
def read_acam_status(self):
self.tdc_regs.wr_reg(0xFC, 0x10)
return self.tdc_regs.rd_reg(0x70)
def enable_channels(self):
print "Enabling channels"
self.tdc_regs.wr_bit(0x84, 7, 1)
def disable_channels(self):
print "Disabling channels"
self.tdc_regs.wr_bit(0x84, 7, 0)
def channel_term(self, channel, enable):
self.tdc_regs.wr_bit(0x84, channel-1, enable)
#print "0x%08X"%self.tdc_regs.rd_reg(0x84)
def set_utc(self, utc):
self.tdc_regs.wr_reg(0x80, utc)
self.tdc_regs.wr_reg(0xFC, 0x200)
def get_utc(self):
return self.tdc_regs.rd_reg(0xA0)
def start_acq(self):
self.tdc_regs.wr_reg(0xFC, 0x1)
print "Aquisition started!"
def tdc_core_test(self):
for i in range(0,150,4):
print "Iteration %d: reg[%.3X]: 0x%.8X" %(i/4, i, self.tdc_regs.rd_reg(i))
time.sleep(0.5)
return self.tdc_regs.rd_reg(0xFC)
#...dummy...#
def generate_dummy_irq(self):
self.tdc_regs.wr_reg(0xFC, 0x80000000)
print "Generating dummy IRQ.."
#...dummy...#
def set_irq_tstamp_thresh(self,tstamp_thresh):
print "Setting IRQ timestamps threshold"
self.tdc_regs.wr_reg(0x90, tstamp_thresh) # irq tstaps threshold; only 9 LSbits are significant
def set_irq_time_thresh(self, time_thresh):
print "Setting IRQ time threshold"
self.tdc_regs.wr_reg(0x94, time_thresh) # irq time (sec) threshold
def stop_acq(self):
self.tdc_regs.wr_reg(0xFC, 0x2)
print "Aquisition stopped."
def get_pointer(self):
return (self.WP_MASK & self.tdc_regs.rd_reg(0xA8))
def get_pointer2(self):
return (self.tdc_regs.rd_reg(0xA8))
def get_overflow_counter(self):
return ((self.WP_OVERFLOW_MASK & self.tdc_regs.rd_reg(0xA8)) >> 12)
# Set IRQ enable mask
def set_irq_en_mask(self, mask):
self.irq_controller.wr_reg(self.IRQ_CTRL_EN_MASK, mask)
return self.irq_controller.rd_reg(self.IRQ_CTRL_EN_MASK)
# Get IRQ source
def get_irq_src(self):
return self.irq_controller.rd_reg(self.IRQ_CTRL_SRC)
# Clear IRQ source
def clear_irq_src(self, src):
self.irq_controller.wr_bit(self.IRQ_CTRL_SRC, src, 1)
# Check for IRQs
def check_irq(self, verbose=0):
self.gnum.irq_en()
self.gnum.wait_irq()
if(verbose):
print('#################!!!!GN4124 interrupt occured!!!!#################')
def get_timestamps(self, verbose=0):
# Read the number of bytes to be read from the board
dma_length_tmp = self.get_pointer()
if dma_length_tmp == 0: # add overflow> 0
dma_length = 4096
else:
dma_length = dma_length_tmp
carrier_addr = 0x0
# Calculate the number of DMA item required to get the data
items_required = int(math.ceil(dma_length/float(self.DMA_LENGTH)))
if(128 < items_required):
print('Required items: %d')%items_required
raise Exception('Current gn4124 class only supports up to 128 items.')
if(verbose):
print('Required items: %d')%items_required
# Configure DMA
for num in range(items_required):
if(items_required == num+1):
next_item = 0
item_length = (dma_length-(num*self.DMA_LENGTH))
else:
next_item = 1
item_length = self.DMA_LENGTH
if(0 == num):
item_start_addr = carrier_addr
else:
item_start_addr = carrier_addr + (num*self.DMA_LENGTH)
if(verbose):
print("item nb:%d item_carrier_addr:0x%.8X item_host_addr:0x%.8X item_length:%d next_item:%d)")%(num,item_start_addr,self.dma_pages[num+1],item_length,next_item)
self.gnum.add_dma_item(item_start_addr, self.dma_pages[num+1], item_length, 0, next_item)
if(verbose):
if(items_required > 1):
items = self.gnum.get_memory_page(0)
print('DMA items:')
for i in range(items_required*8):
print('%.4X: %.8X')%(i*4,items[i])
# Start DMA
dma_finished = 0
if(verbose):
print "Start DMA"
self.gnum.start_dma()
"""
# Poll on DMA status
print "Wait for DMA done"
while('Done' == self.gnum.get_dma_status()):
time.sleep(0.01)
print "DMA done!"
"""
# Wait for end of DMA interrupt
if(verbose):
print('Wait GN4124 interrupt')
self.gnum.wait_irq()
if(verbose):
print('GN4124 interrupt occured')
"""
print('irq mask:%.4X')%self.get_irq_en_mask() if(verbose)
while(0 == dma_finished):
irq_src = self.get_irq_source()
if(verbose):
print('IRQ source : %.4X')%irq_src
print('DMA status: %s')%self.gnum.get_dma_status()
if(irq_src & self.IRQ_SRC_DMA_END):
print('IRQ source : %.4X')%irq_src if(verbose)
self.clear_irq_source(self.IRQ_SRC_DMA_END)
print('IRQ source : %.4X')%self.get_irq_source() if(verbose)
dma_finished = 1
time.sleep(0.005)
print('DMA finished!') if(verbose)
"""
# Retrieve data from host memory
data = []
for i in range(items_required):
data += self.gnum.get_memory_page(i+1)
if(verbose):
print('data length:%d')%(len(data)*4)
for i in range(len(data)):
print data[i]
# Format timestamps
if(verbose):
print "Timestamps retreived:"
raw_timestamps = []
timestamps = []
for i in range(0,dma_length/4,4):
# timestamp value
timestamp = data[i+2] * 1E12 + data[i+1] * 8E3 + data[i] * 81.03
# timestamp metadata
channel = self.META_CHANNEL_MASK & data[i+3]
slope = ((self.META_SLOPE_MASK & data[i+3]) >> 4)
fifo_lf = ((self.META_FIFO_LF_MASK & data[i+3]) >> 8)
fifo_ef = ((self.META_FIFO_EF_MASK & data[i+3]) >> 12)
# putting everything together
raw_timestamps.append((data[i+3]<<96)+(data[i+2]<<64)+(data[i+1]<<32)+data[i])
timestamps.append([timestamp, channel, slope, fifo_lf, fifo_ef])
#if(verbose):
# print "[%03d] sec:%20.3f channel:%d slope:%7s fifo_lf:%d fifo_ef:%d"%(i/4,timestamp, channel, self.META_SLOPE[slope], fifo_lf, fifo_ef)
eurika = 0
for i in range(0,dma_length/4,8):
# for debug check if UTC second changes
if (data[i+2] != data[i+6]):
#print "Euriika! second changed in these timestamps"
eurika = 1
if(verbose):
print "Number of timestamps = %d" % (len(timestamps))
for i in range(len(timestamps)):
print timestamps[i]
return timestamps, data
if __name__ == '__main__' :
main()
......@@ -15,13 +15,32 @@
## |
## Description Testing of the TDC_IN_FPGA lines of the TDC board. |
## |
## The test uses the Fine Delay as pulse genrator. A 1 ms pulse is sent to each TDC |
## channel and is being registered by the dedicated counters in the FPGA. |
## Each FPGA counter is running with 100 MHz clock, therefore around 1K cycles are |
## expected to be counted. |
## The channels enable and terminations enable should be functional for the test to |
## succeed. |
## Note that for this test none of the ACAM logic is used. |
## In order to simplify the testing procedure, this test uses the same setup that is |
## used for the TDC calibration (*). |
## The Pendulum serves as the pulse generator; it is programmed to send pulses of |
## 100 ms pulse width, 500 ms period. |
## The output of the Pendulum is fed to a Timetech Fanout unit, from where we use |
## two outputs. |
## The USB-interconnection-box is used for the distribution of the two Timetech |
## Fanout outputs to the five TDC input channels. |
## The USB-interconnection-box channel 1 is constantly connected to the |
## TDC-under-test channel 1. The other Timetech Fanout output can be sent to any of |
## the TDC-under-test channels 2, 3, 4, 5, according to the command sent to the box. |
## |
## During the test we send pulses to each one of the TDC channels; inside the FPGA, |
## a dedicated counter per channel is running at 100 MHz (=cycles of 10 ns) and is |
## counting the number of cycles when the corresponding channel is at '1'. |
## For each channel, the Pendulum stays ON for one second; with 100 ms pulse width |
## and 500 ms period, we are expecting two 100 ms pulses to arrive to the FPGA. |
## Therefore, inside the FPGA, a counter is expected to count 20 M cycles. |
## Note however that because of the nature of the USB-interconnection-box, we cannot |
## be sending pulses to all the channels simultaneously, but only to the pairs: |
## (ch 1, ch 2), (ch 1, ch 3), (ch 1, ch 4), (ch 1, ch 5). |
## This means that channel 1 is expected to register 4 times more cycles that the |
## rest of the channels, that is 80 M. |
## Note also that he channels-enable and terminations-enable signals should be |
## functional for the test to succeed. |
## Note finally that for this test none of the ACAM logic is used. |
## |
## The counter for TDC_IN_FPGA_1 can be accessed at PCIe address x00080 |
## The counter for TDC_IN_FPGA_2 can be accessed at PCIe address x00084 |
......@@ -37,6 +56,10 @@
## bit 4: TERM_EN_4 |
## bit 5: TERM_EN_5 |
## |
## (*) For this test it would have been more straight-forward to use five outputs |
## of the Timetech Fanout unit; however, not to change the setup that is essential |
## for the calibration tests that follow, we are only using two channels and the |
## USB-interconnection-box. |
## |
## FW to load tdc_pts_input_pulse.bit |
## Authors Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
......@@ -67,36 +90,57 @@ import sys
import time
import os
import math
from numpy import *
from ctypes import *
from datetime import datetime
# Add common modules location tp path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
# Add common modules location to path
sys.path.append('../../../../pts/')
sys.path.append('../../../../pts/gnurabbit/python/')
sys.path.append('../../../../pts/common/')
sys.path.append('../../../../pts/common/usb_box')
sys.path.append('../../../../pts/common/cp210x')
# Import common modules
from ptsexcept import *
import rr
import csr
# Import specific modules
import fmc_tdc
sys.path.append('../../../common/fmc_delay/software/python/')
import fdelay_lib
from cp210x_eeprom import *
from PendulumCNT91 import *
from calibr_box import *
from find_usb_tty import *
# Pendulum
PENDULUM = "/dev/usbtmc1"
USB_DEVICE = "/dev/ttyUSB0"
RS232_BAUD = 57600
def pendulum_output_on(meas):
meas.write("OUTP:TYPE PULS")
meas.write("SOUR:PULS:PER 0.5")
meas.write("SOUR:PULS:WIDT 0.1")
return (1)
def pendulum_output_off(meas):
meas.write("OUTP:TYPE OFF")
return (1)
# USB-interconnection-box
BOX_USB_VENDOR_ID = 0x10c4 # Cygnal Integrated Products, Inc.
BOX_USB_DEVICE_ID = 0xea60 # CP210x Composite Device
def main (default_directory='.'):
# Constants declaration
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_pts_input_pulse.bit'
FMC_DELAY_ADDR = '1a39:0004/1a39:0004@0005:0000'
FMC_DELAY_BITSTREAM_PATH = '../firmwares/fmc_delay_spec.bin'
FPGA_LOADER_PATH = '../../../gnurabbit/user/fpga_loader'
FMC_TDC_CHANNEL_NB = 5
start_test_time = time.time()
#-----> PCIe address, firmware, loader constants
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_pts_input_pulse.bit'
FPGA_LOADER_PATH = '../../../../pts/gnurabbit/user/fpga_loader'
#-----> FPGA constants
# Addressing for the retrieval of carrier csr information
CARRIER_CSR = 0x00000 # base address
CSR_TYPE_VER = 0x00
......@@ -117,18 +161,23 @@ def main (default_directory='.'):
CHANNEL_5_COUNTER = 0x90
CHANNEL_COUNTERS = [0x80, 0x84, 0x88, 0x8C, 0x90]
#-----> FPGA initializations
# SPEC object declaration
spec = rr.Gennum()
#-----> TDC
# Bind SPEC object to FMC TDC card
print "\n-------------------------------------------------------------------"
print "----------------------------- FMC TDC -----------------------------"
print "------------------------- TDC_IN_FPGA test ------------------------\n"
print ("Test of the TDC_IN_FPGA[5..1] signals. The test is using the Fine Delay\n"
"board as pulse generator, sending pulses to each one of the TDC channels.\n"
"Dedicated counters in the carrier FPGA are counting the duration of the pulses.\n")
print ("Test of the TDC_IN_FPGA[5..1] signals. The test is using the\n"
"Pendulum as pulse generator as well as the Timetch Fanout and the\n"
"USB-interconnection-box for the distribution of the pulses to all\n"
"the TDC input channels.\n"
"Dedicated counters in the carrier FPGA are counting the duration\n"
"of the pulses.\n"
"Note that for this test none of the ACAM logic is used.\n")
print "\n_______________________________Info______________________________\n"
print "FMC TDC address to parse: %s"%(FMC_TDC_ADDR)
for name, value in spec.parse_addr(FMC_TDC_ADDR).iteritems():
......@@ -142,19 +191,17 @@ def main (default_directory='.'):
print "Loading FMC TDC firmware...",
firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
bitstream = os.path.join(default_directory, FMC_TDC_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
os.system(firmware_loader + ' ' + bitstream )
time.sleep(1)
firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
bitstream = os.path.join(default_directory, FMC_TDC_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
os.system(firmware_loader + ' ' + bitstream )
time.sleep(1)
print "Firmware loaded!"
# Check bitsteam type
bitstream_type = carrier_csr.rd_reg(CSR_BSTM_TYPE)
print('Bitstream type : 0x%.8X') % bitstream_type
print('Bitstream type :%.8X') % bitstream_type
if(bitstream_type == 0xFFFFFFFF):
msg = ("FATAL ERROR: Firmware not properly loaded")
msg = ("FATAL ERROR: Wrong bitstream type loaded")
os.close(spec.fd)
print (msg)
raise PtsCritical (msg)
......@@ -162,9 +209,11 @@ def main (default_directory='.'):
msg = ("FATAL ERROR: Wrong bitstream type loaded")
os.close(spec.fd)
print (msg)
raise PtsCritical (msg)
raise PtsCritical (msg)
# Carrier Information
print "\n___________________________Carrier info__________________________\n"
print("PCB version : %d") % (PCB_VER_MASK & carrier_csr.rd_reg(CSR_TYPE_VER))
print("Carrier type : %d") % ((CARRIER_TYPE_MASK & carrier_csr.rd_reg(CSR_TYPE_VER))>>16)
print("Bitstream type : 0x%.8X") % (carrier_csr.rd_reg(CSR_BSTM_TYPE))
......@@ -173,85 +222,75 @@ def main (default_directory='.'):
print("Control : 0x%.8X") % (carrier_csr.rd_reg(CSR_CTRL))
# Check mezzanine presence flag
print "\n__________________________Presence test__________________________\n"
status = carrier_csr.rd_reg(CSR_STATUS)
if(status & STATUS_FMC_PRES):
print('Carrier csr status : 0x%.8X') % status
msg = ("FATAL ERROR: Mezzanine appears missing.")
print('Carrier csr status :%.8X') % status
msg = ("ERROR: Mezzanine appears missing.")
os.close(spec.fd)
print (msg)
raise PtsCritical (msg)
else:
print("Mezzanine present : OK")
print("Mezzanine present OK\n")
#-----> TDC setup
# Enable input logic
# Channels enable activated
# Termination enable of channels 1,2,3,4 activated;
# channels 4 and 5 are receiving the same Fine Delay pulse, only ch 4 termination activated
carrier_csr.wr_reg(INPUT_EN, 0x1F)
# Termination enable of all the channels activated;
carrier_csr.wr_reg(INPUT_EN, 0x3F)
# Check FPGA counters
counter_error = 0
for i in CHANNEL_COUNTERS:
if (carrier_csr.rd_reg(i) != 0):
msg = (("ERROR: Unexpected failure of FPGA counter 0x%.2X; received 0x%.8X, expected 0x00000000")%(i, carrier_csr.rd_reg(i)))
os.close(spec.fd)
print (msg)
raise PtsError (msg)
counter_error = 1
if (counter_error == 0):
print("Counters init : OK")
#-----> Fine Delay
print "\n___________________________Fine Delay____________________________"
print "\nFine Delay initializations.."
# Bind SPEC object to FMC Fine Delay card
print "Fine Delay address to parse %s"%(FMC_DELAY_ADDR)
for name, value in spec.parse_addr(FMC_DELAY_ADDR).iteritems():
print "%s:0x%04X"%(name, value)
spec.bind(FMC_DELAY_ADDR)
#-----> Interconnection Box
# Communication and setup of Interconnection box
print "\n_____________________USB interconnection box______________________\n"
box_tty = CttyUSB().find_usb_tty(BOX_USB_VENDOR_ID, BOX_USB_DEVICE_ID)
print("Device: %s" % box_tty[0])
box = CCalibr_box(box_tty[0])
box.select_trigger_loopback(0)
box.select_output(4)
#-----> Pendulum
print "\n__________________________USB Pendulum_____________________________\n"
try:
meas = PendulumCNT91(PENDULUM)
except OSError:
raise PtsError('CNT-91 is not switched on or badly connected, aborting.')
a = pendulum_output_off(meas)
# Load FMC Fine Delay firmware
print "\nLoading FMC Fine Delay firmware...",
sys.stdout.flush()
firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
bitstream = os.path.join(default_directory, FMC_DELAY_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
time.sleep(1)
print "Firmware loaded!"
# Fine Delay object declaration
try:
fdelay = fdelay_lib.FineDelay(spec.get_fd())
except:
msg = ("ERROR: Fine Delay board Initiliazation failed")
os.close(spec.fd)
print (msg)
raise PtsError (msg)
# Set UTC and Coarse time in the Fine Delay
fdelay.set_time(0, 0)
fd_time = fdelay_lib.fd_timestamp()
fd_time = fdelay.get_time()
# Configure the Fine Delay as a pulse generator
enable = 1
t_start_coarse = 0
width = 1000000000 # pulse width 1 ms
delta = 2000000000
count = 1
t_start_utc = fdelay.get_time().utc+1 # starting in 1 sec
fdelay.conf_pulsegen(1, enable, t_start_utc, t_start_coarse, width, delta, count)
fdelay.conf_pulsegen(2, enable, t_start_utc, t_start_coarse, width, delta, count)
fdelay.conf_pulsegen(3, enable, t_start_utc, t_start_coarse, width, delta, count)
fdelay.conf_pulsegen(4, enable, t_start_utc, t_start_coarse, width, delta, count)
print ("\nFine delay sending one pulse per channel of 1ms width..")
#-----> TDC
time.sleep(2)
# Bind SPEC object to FMC TDC card
spec.bind(FMC_TDC_ADDR)
#-----> Sending pulses to all the channels
for i in range(4): # for the 4 pairs of channels (1,2), (1,3), (1,4), (1,5)
otherch = i+1
r_edge_timestamps_ch1 = []
r_edge_timestamps_otherch = []
all_measurs = []
# USB-interconnection-box
box.select_trigger_loopback(0)
box.select_output(4-i)
# pendulum output on
a = pendulum_output_on(meas)
# pendulum sending pulses
time.sleep(1.2)
# pendulum output off
a = pendulum_output_off(meas)
#-----> Results
print "\n___________________________Results_______________________________\n"
# string to keep the ERROR messages from all the channels
......@@ -263,21 +302,29 @@ def main (default_directory='.'):
msg = (("ERROR: TDC_IN_FPGA%d: No pulse arrived ")%(CHANNEL_COUNTERS.index(i)+1))
print (msg)
all_msg+=msg
elif (carrier_csr.rd_reg(i) > 100500) or (carrier_csr.rd_reg(i) < 95000): # 0.5% acceptance limit
msg = (("ERROR: TDC_IN_FPGA%d: Pulse width %.5f ms is outside accepted limits [1.005 ms .. 0.995 ms] ")%(CHANNEL_COUNTERS.index(i)+1, carrier_csr.rd_reg(i)/1e5))
# channel 1 should have registered 4 times more cycles
elif (((CHANNEL_COUNTERS.index(i)+1)== 1) and ((round(carrier_csr.rd_reg(i)/1e6) > 4* 30) or (round(carrier_csr.rd_reg(i)/1e6) < 4*10))):
msg = (("ERROR: TDC_IN_FPGA%d: Counted %dM cycles; expected 80M")%(CHANNEL_COUNTERS.index(i)+1, round(carrier_csr.rd_reg(i)/1e6)))
print (msg)
all_msg+=msg
# rest of channels
elif (((CHANNEL_COUNTERS.index(i)+1) > 1) and ((round(carrier_csr.rd_reg(i)/1e6) > 30) or (round(carrier_csr.rd_reg(i)/1e6) < 10))): # 0.5% acceptance limit
msg = (("ERROR: TDC_IN_FPGA%d: Counted %dM cycles; expected 20M ")%(CHANNEL_COUNTERS.index(i)+1, round(carrier_csr.rd_reg(i)/1e6)))
print (msg)
all_msg+=msg
else:
print("TDC_IN_FPGA%d: Pulse width %.5f ms OK")%(CHANNEL_COUNTERS.index(i)+1, carrier_csr.rd_reg(i)/1e5)
print("TDC_IN_FPGA%d: Counted %dM cycles OK")%(CHANNEL_COUNTERS.index(i)+1, round(carrier_csr.rd_reg(i)/1e6))
if (all_msg != ""):
os.close(spec.fd)
raise PtsError (all_msg)
os.close(spec.fd)
print "\n\n-----------------------------------------------------------------"
print "\n\n--------------------------------"
end_test_time = time.time()
print "Test elapsed time: %.2f seconds\n\n\n" % (end_test_time-start_test_time)
if __name__ == '__main__' :
main()
......@@ -13,11 +13,20 @@
## |
##-------------------------------------------------------------------------------------------------
## |
## Description Testing of the ENABLE_INPUTS signal of the TDC board. |
## Description Testing of the TDC_IN_FPGA lines of the TDC board. |
## |
## The test uses the Fine Delay as pulse genrator. Pulses are sent to all the |
## inputs with the enable activated and then deactivated. |
## Through the TDC_IN_FPGA signals we monitor the arrival of the pulses. |
## In order to simplify the testing procedure, this test uses the same setup that is |
## used for the TDC calibration (*). |
## The Pendulum serves as the pulse generator; it is programmed to send pulses of |
## 100 ms pulse width, 500 ms period. |
## The output of the Pendulum is fed to a Timetech Fanout unit, from where we use |
## two outputs. |
## The USB-interconnection-box is used for the distribution of the two Timetech |
## Fanout outputs to the five TDC input channels. |
## The USB-interconnection-box channel 1 is constantly connected to the |
## TDC-under-test channel 1. The other Timetech Fanout output can be sent to any of |
## the TDC-under-test channels 2, 3, 4, 5, according to the command sent to the box. |
## Pulses are sent to all the inputs with the enable activated and then deactivated. |
## Dedicated counters in the FPGA register the input pulses. |
## Note that for this test none of the ACAM logic is used. |
## |
......@@ -26,7 +35,6 @@
## The counter for TDC_IN_FPGA_3 can be accessed at PCIe address x00088 |
## The counter for TDC_IN_FPGA_4 can be accessed at PCIe address x0008C |
## The counter for TDC_IN_FPGA_5 can be accessed at PCIe address x00090 |
## The counters reset can be accessed at PCIe address x00024 |
## |
## The channels and terminations enable can be accessed at PCIe address x000A0: |
## bit 0: ENABLE_INPUTS |
......@@ -66,38 +74,57 @@ import sys
import time
import os
import math
from numpy import *
from ctypes import *
from datetime import datetime
# Add common modules location tp path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
# Add common modules location to path
sys.path.append('../../../../pts/')
sys.path.append('../../../../pts/gnurabbit/python/')
sys.path.append('../../../../pts/common/')
sys.path.append('../../../../pts/common/usb_box')
sys.path.append('../../../../pts/common/cp210x')
# Import common modules
from ptsexcept import *
import rr
import csr
import fmc_tdc
from cp210x_eeprom import *
from PendulumCNT91 import *
from calibr_box import *
from find_usb_tty import *
# Pendulum
PENDULUM = "/dev/usbtmc1"
USB_DEVICE = "/dev/ttyUSB0"
RS232_BAUD = 57600
# Import specific modules
import fmc_tdc
sys.path.append('../../../common/fmc_delay/software/python/')
import fdelay_lib
def pendulum_output_on(meas):
meas.write("OUTP:TYPE PULS")
meas.write("SOUR:PULS:PER 0.5")
meas.write("SOUR:PULS:WIDT 0.1")
return (1)
def pendulum_output_off(meas):
meas.write("OUTP:TYPE OFF")
return (1)
# USB-interconnection-box
BOX_USB_VENDOR_ID = 0x10c4 # Cygnal Integrated Products, Inc.
BOX_USB_DEVICE_ID = 0xea60 # CP210x Composite Device
def main (default_directory='.'):
# Constants declaration
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_pts_input_pulse.bit'
FMC_DELAY_ADDR = '1a39:0004/1a39:0004@0005:0000'
FMC_DELAY_BITSTREAM_PATH = '../firmwares/fmc_delay_spec.bin'
FPGA_LOADER_PATH = '../../../gnurabbit/user/fpga_loader'
FMC_TDC_CHANNEL_NB = 5
start_test_time = time.time()
#-----> PCIe address, firmware, loader constants
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_pts_input_pulse.bit'
FPGA_LOADER_PATH = '../../../../pts/gnurabbit/user/fpga_loader'
#-----> FPGA constants
# Addressing for the retrieval of carrier csr information
CARRIER_CSR = 0x00000 # base address
CSR_TYPE_VER = 0x00
......@@ -119,20 +146,24 @@ def main (default_directory='.'):
CHANNEL_5_COUNTER = 0x90
CHANNEL_COUNTERS = [0x80, 0x84, 0x88, 0x8C, 0x90]
#-----> FPGA initializations
# SPEC object declaration
spec = rr.Gennum()
#-----> TDC
# Bind SPEC object to FMC TDC card
print "\n-------------------------------------------------------------------"
print "----------------------------- FMC TDC -----------------------------"
print "--------------------- TDC_IN_FPGA disable test --------------------\n"
print ("Test of the EN_INPUTS signal. The test is using the Fine Delay board\n"
"as pulse generator, sending pulses to each one of the TDC channels.\n"
"Dedicated counters in the carrier FPGA are counting the duration of the pulses.\n"
"When the EN_INPUTS is active, pulses should be arriving to all the channels;\n"
"when the EN_INPUTS is disabled no pulse should arrive.\n")
print ("Test of the EN_INPUTS signal. The test is using the Pendulum\n"
"as pulse generator as well as the Timetch Fanout and the\n"
"USB-interconnection-box for the distribution of the pulses to\n"
"all the TDC input channels.\n"
"Dedicated counters in the carrier FPGA are counting the duration\n"
"of the pulses. When the EN_INPUTS is active, pulses should be\n"
"arriving to all the channels; when the EN_INPUTS is disabled no\n"
"pulse should arrive.\n"
"Note that for this test none of the ACAM logic is used.\n")
print "\n_______________________________Info______________________________\n"
print "FMC TDC address to parse: %s"%(FMC_TDC_ADDR)
......@@ -147,18 +178,17 @@ def main (default_directory='.'):
print "Loading FMC TDC firmware...",
firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
bitstream = os.path.join(default_directory, FMC_TDC_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
os.system(firmware_loader + ' ' + bitstream )
time.sleep(1)
firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
bitstream = os.path.join(default_directory, FMC_TDC_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
os.system(firmware_loader + ' ' + bitstream )
time.sleep(1)
print "Firmware loaded!"
# Check bitsteam type
bitstream_type = carrier_csr.rd_reg(CSR_BSTM_TYPE)
print('Bitstream type :%.8X') % bitstream_type
if(bitstream_type == 0xFFFFFFFF):
msg = ("FATAL ERROR: Firmware not properly loaded")
msg = ("FATAL ERROR: Wrong bitstream type loaded")
os.close(spec.fd)
print (msg)
raise PtsCritical (msg)
......@@ -166,8 +196,10 @@ def main (default_directory='.'):
msg = ("FATAL ERROR: Wrong bitstream type loaded")
os.close(spec.fd)
print (msg)
raise PtsCritical (msg)
raise PtsCritical (msg)
# Carrier Information
print "\n___________________________Carrier info__________________________\n"
print("PCB version : %d") % (PCB_VER_MASK & carrier_csr.rd_reg(CSR_TYPE_VER))
print("Carrier type : %d") % ((CARRIER_TYPE_MASK & carrier_csr.rd_reg(CSR_TYPE_VER))>>16)
print("Bitstream type : 0x%.8X") % (carrier_csr.rd_reg(CSR_BSTM_TYPE))
......@@ -175,82 +207,71 @@ def main (default_directory='.'):
print("Status : 0x%.8X") % (carrier_csr.rd_reg(CSR_STATUS))
print("Control : 0x%.8X") % (carrier_csr.rd_reg(CSR_CTRL))
# Check mezzanine presence flag
print "\n__________________________Presence test__________________________\n"
status = carrier_csr.rd_reg(CSR_STATUS)
if(status & STATUS_FMC_PRES):
msg = ('FATAL ERROR: Mezzanine appears missing.')
print('Carrier csr status :%.8X') % status
msg = ("ERROR: Mezzanine appears missing.")
os.close(spec.fd)
print (msg)
raise PtsCritical (msg)
raise PtsCritical (msg)
else:
print("Mezzanine present : OK")
print("Mezzanine present OK\n")
#-----> ############## Input logic Disabled ##############
carrier_csr.wr_reg(INPUT_EN, 0x00)
# Check FPGA counters
counter_error = 0
for i in CHANNEL_COUNTERS:
if (carrier_csr.rd_reg(i) != 0):
msg = (("ERROR: Unexpected failure of FPGA counter 0x%.2X; received 0x%.8X, expected 0x00000000")%(i, carrier_csr.rd_reg(i)))
os.close(spec.fd)
print (msg)
raise PtsError (msg)
counter_error = 1
if (counter_error == 0):
print("Counters init : OK")
#-----> Interconnection Box
# Communication and setup of Interconnection box
print "\n_____________________USB interconnection box______________________\n"
box_tty = CttyUSB().find_usb_tty(BOX_USB_VENDOR_ID, BOX_USB_DEVICE_ID)
print("Device: %s" % box_tty[0])
box = CCalibr_box(box_tty[0])
box.select_trigger_loopback(0)
box.select_output(4)
#-----> Pendulum
# Communication with Pendulum
print "\n__________________________USB Pendulum_____________________________\n"
try:
meas = PendulumCNT91(PENDULUM)
except OSError:
raise PtsError('CNT-91 is not switched on or badly connected, aborting.')
a = pendulum_output_off(meas)
################################## Input logic Disabled ##################################
carrier_csr.wr_reg(INPUT_EN, 0x00)
#-----> Sending pulses
for i in range(4): # for the 4 pairs of channels (1,2), (1,3), (1,4), (1,5)
otherch = i+1
r_edge_timestamps_ch1 = []
r_edge_timestamps_otherch = []
all_measurs = []
#-----> Fine Delay
print "\n___________________________Fine Delay____________________________"
print "\nFine Delay initializations.."
# Bind SPEC object to FMC Fine Delay card
print "Fine Delay address to parse %s"%(FMC_DELAY_ADDR)
for name, value in spec.parse_addr(FMC_DELAY_ADDR).iteritems():
print "%s:0x%04X"%(name, value)
spec.bind(FMC_DELAY_ADDR)
# USB-interconnection-box
box.select_trigger_loopback(0)
box.select_output(4-i)
# Load FMC Fine Delay firmware
print "\nLoading FMC Fine Delay firmware...",
sys.stdout.flush()
firmware_loader = os.path.join(default_directory, FPGA_LOADER_PATH)
bitstream = os.path.join(default_directory, FMC_DELAY_BITSTREAM_PATH)
os.system(firmware_loader + ' ' + bitstream)
time.sleep(1)
print "Firmware loaded!"
# pendulum output on
a = pendulum_output_on(meas)
# pendulum sending pulses
time.sleep(1.2)
# pendulum output off
a = pendulum_output_off(meas)
# Fine Delay object declaration
try:
fdelay = fdelay_lib.FineDelay(spec.get_fd())
except:
msg = ("ERROR: Fine Delay board Initiliazation failed")
os.close(spec.fd)
print (msg)
raise PtsError (msg)
# Set UTC and Coarse time in the Fine Delay
fdelay.set_time(0, 0)
fd_time = fdelay_lib.fd_timestamp()
fd_time = fdelay.get_time()
# Configure the Fine Delay as a pulse generator
enable = 1
t_start_coarse = 0
width = 1000000000 # pulse width 1 ms
delta = 2000000000
count = 1
t_start_utc = fdelay.get_time().utc+1 # starting in 1 sec
fdelay.conf_pulsegen(1, enable, t_start_utc, t_start_coarse, width, delta, count)
fdelay.conf_pulsegen(2, enable, t_start_utc, t_start_coarse, width, delta, count)
fdelay.conf_pulsegen(3, enable, t_start_utc, t_start_coarse, width, delta, count)
fdelay.conf_pulsegen(4, enable, t_start_utc, t_start_coarse, width, delta, count)
print ("\nFine delay sending one pulse per channel of 1ms width..")
#-----> TDC
time.sleep(2)
# Bind SPEC object to FMC TDC card
spec.bind(FMC_TDC_ADDR)
# string to keep the ERROR messages from all the channels
all_msg = ""
......@@ -260,39 +281,46 @@ def main (default_directory='.'):
# Read counters
for i in CHANNEL_COUNTERS:
if (carrier_csr.rd_reg(i) != 0):
msg = (("ERROR: ENABLE_INPUTS disabled: TDC_IN_FPGA%d failure; pulse of %.5f ms arrived ")%(CHANNEL_COUNTERS.index(i)+1,carrier_csr.rd_reg(i)/1e5))
msg = (("ERROR: ENABLE_INPUTS disabled: TDC_IN_FPGA%d failure; Counted %dM cycles")%(CHANNEL_COUNTERS.index(i)+1,round(carrier_csr.rd_reg(i)/1e6)))
print (msg)
all_msg+=msg
else:
print("ENABLE_INPUTS disabled: TDC_IN_FPGA%d OK") %(CHANNEL_COUNTERS.index(i)+1)
################################## Input logic Enabled ##################################
#-----> ############## Input logic Enabled ##############
carrier_csr.wr_reg(INPUT_EN, 0x1F)
carrier_csr.wr_reg(RST_COUNTERS,0x1)
time.sleep(0.1)
carrier_csr.wr_reg(RST_COUNTERS,0x0)
#-----> Sending pulses
for i in range(4): # for the 4 pairs of channels (1,2), (1,3), (1,4), (1,5)
#-----> Fine Delay
spec.bind(FMC_DELAY_ADDR)
t_start_utc = fdelay.get_time().utc+1 # starting in 1 sec
fdelay.conf_pulsegen(1, enable, t_start_utc, t_start_coarse, width, delta, count)
fdelay.conf_pulsegen(2, enable, t_start_utc, t_start_coarse, width, delta, count)
fdelay.conf_pulsegen(3, enable, t_start_utc, t_start_coarse, width, delta, count)
fdelay.conf_pulsegen(4, enable, t_start_utc, t_start_coarse, width, delta, count)
otherch = i+1
r_edge_timestamps_ch1 = []
r_edge_timestamps_otherch = []
all_measurs = []
#-----> TDC
time.sleep(2)
# Bind SPEC object to FMC TDC card
spec.bind(FMC_TDC_ADDR)
# USB-interconnection-box
box.select_trigger_loopback(0)
box.select_output(4-i)
# pendulum output on
a = pendulum_output_on(meas)
# pendulum sending pulses
time.sleep(1.2)
# pendulum output off
a = pendulum_output_off(meas)
print "\n______________________Input logic Enabled________________________\n"
# Read counters
for i in CHANNEL_COUNTERS:
if (carrier_csr.rd_reg(i) != 0):
print("ENABLE_INPUTS enabled: TDC_IN_FPGA%d OK")%(CHANNEL_COUNTERS.index(i)+1)
print("ENABLE_INPUTS enabled: TDC_IN_FPGA%d OK! Counted %dM cycles ")%(CHANNEL_COUNTERS.index(i)+1,round(carrier_csr.rd_reg(i)/1e6))
else:
msg = (("ERROR: ENABLE_INPUTS enabled: TDC_IN_FPGA%d: No pulse arrived ")%(CHANNEL_COUNTERS.index(i)+1))
print (msg)
......@@ -302,8 +330,10 @@ def main (default_directory='.'):
os.close(spec.fd)
raise PtsError (all_msg)
os.close(spec.fd)
print "\n\n-----------------------------------------------------------------"
print "\n\n--------------------------------"
end_test_time = time.time()
print "Test elapsed time: %.2f seconds\n\n\n" % (end_test_time-start_test_time)
if __name__ == '__main__' :
main()
......@@ -21,7 +21,7 @@
## if all the LEDs are blinking as expected. |
## |
## |
## FW to load .bin |
## FW to load tdc_pts_leds.bit |
## Authors Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
## Website http://www.ohwr.org/projects/pts |
## Date 11/01/2013 |
......@@ -49,11 +49,13 @@
import sys
import time
import os
import math
from datetime import datetime
# Add common modules location tp path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
sys.path.append('../../../../pts/')
sys.path.append('../../../../pts/gnurabbit/python/')
sys.path.append('../../../../pts/common/')
# Import common modules
from ptsexcept import *
......@@ -61,24 +63,27 @@ import rr
import csr
def main (default_directory='.'):
start_test_time = time.time()
# Constants declaration
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_pts_leds.bit'
FPGA_LOADER_PATH = '../../../gnurabbit/user/fpga_loader'
FPGA_LOADER_PATH = '../../../../pts/gnurabbit/user/fpga_loader'
print "\n-------------------------------------------------------------------"
print "----------------------------- TDC PTS -----------------------------"
print "---------------------------- LEDs test ----------------------------\n"
print ("Test of the front panel LEDs. For this test the operator’s intervention\n"
"is needed; when prompted, the operator should visually inspect the LEDs.\n")
print ("Test of the front panel LEDs. For this test the operator’s\n"
"intervention is needed; when prompted, the operator should visually\n"
"inspect the LEDs.\n")
#-----> FPGA initializations
# SPEC object declaration
spec = rr.Gennum()
print "\n_________________________Initialisations_________________________\n"
# Load FMC TDC firmware
print "Loading FMC TDC firmware...",
......@@ -89,6 +94,7 @@ def main (default_directory='.'):
print "Firmware loaded!"
#-----> LEDs inspection
print "\n_________________________LEDs inspection_________________________\n"
# Standard in/out temporary redirection
......@@ -112,8 +118,10 @@ def main (default_directory='.'):
else:
print ("LEDs inspected OK!")
os.close(spec.fd)
print "\n\n-----------------------------------------------------------------"
print "\n\n--------------------------------"
end_test_time = time.time()
print "Test elapsed time: %.2f seconds\n\n\n" % (end_test_time-start_test_time)
if __name__ == '__main__' :
......
#! /bin/bash
ln -s fmc_presence.py test00.py
ln -s clocks.py test01.py
ln -s fpga_inputs.py test02.py
ln -s fpga_inputs_disable.py test03.py
ln -s onewire_test.py test04.py
ln -s eeprom.py test05.py
ln -s acam.py test06.py
ln -s acam_accuracy.py test07.py
ln -s acam_inputs_disable.py test08.py
ln -s acam_startdis_stopdis.py test09.py
ln -s acam_errflag.py test10.py
ln -s dac.py test11.py
ln -s leds.py test12.py
......@@ -24,7 +24,7 @@
## The test reads the unique ID and the temperature and checks if the received |
## values are within reasonable limits. |
## |
## FW to load .bin |
## FW to load tdc_allothertests.bit |
## Authors Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
## Website http://www.ohwr.org/projects/pts |
## Date 11/01/2013 |
......@@ -52,16 +52,14 @@ import sys
import time
import os
# Add common modules location tp path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
# Add common modules location to path
sys.path.append('../../../../pts/')
sys.path.append('../../../../pts/gnurabbit/python/')
sys.path.append('../../../../pts/common/')
# Import common modules
from ptsexcept import *
import rr
# Import specific modules
import fmc_tdc
......@@ -70,13 +68,20 @@ import fmc_tdc
##-------------------------------------------------------------------------------------------------
def main (default_directory='.'):
start_test_time = time.time()
#-----> PCIe address, firmware, loader constants
# Constants declaration
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM_PATH = '../firmwares/tdc_allothertests.bit'
FPGA_LOADER_PATH = '../../../gnurabbit/user/fpga_loader'
FPGA_LOADER_PATH = '../../../../pts/gnurabbit/user/fpga_loader'
#-----> One Wire chip constant
FAMILY_CODE = 0x28
#-----> FPGA initializations
# SPEC object declaration
spec = rr.Gennum()
......@@ -125,6 +130,7 @@ def main (default_directory='.'):
print('Access to TDC core OK')
#-----> Accessing the One Wire chip
# Read unique ID and print to log
print "\n____________________________Unique ID____________________________\n"
try:
......@@ -162,8 +168,10 @@ def main (default_directory='.'):
else:
print('TEMPID IC14: Temperature: %3.2f°C OK') % temp
os.close(spec.fd)
print "\n\n-----------------------------------------------------------------"
print "\n\n--------------------------------"
end_test_time = time.time()
print "Test elapsed time: %.2f seconds\n\n\n" % (end_test_time-start_test_time)
if __name__ == '__main__' :
main()
#! /bin/bash
rm -f test00.py
rm -f test01.py
rm -f test02.py
rm -f test03.py
rm -f test04.py
rm -f test05.py
rm -f test06.py
rm -f test07.py
rm -f test08.py
rm -f test09.py
rm -f test10.py
rm -f test11.py
rm -f test12.py
rm -f test*.pyc
rm -f test*.py~
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment