Commit 69a3e523 authored by Matthieu Cattin's avatar Matthieu Cattin

svec_test37: Add trigger time-tag test for SVEC.

parent 033ed11b
#! ./python
# coding: utf8
# Copyright CERN, 2013
# Author: Matthieu Cattin <matthieu.cattin@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Last modifications: 18/12/2013
# Import system modules
import sys
import time
import os
# Add common modules and libraries location to path
sys.path.append('../../../')
sys.path.append('../../../common/')
sys.path.append('../../../../svec_pts/ubuntu/pts/pyts/')
# Import common modules
from ptsexcept import *
from rr2vv import *
# Import specific modules
from fmc_adc_svec import *
from fmc_adc import *
from numpy import *
"""
svec_test37: Test trigger timetags (single and multi shot modes)
Note: Requires test00.py to run first to load the firmware!
"""
NB_CHANNELS = 4
AWG_SET_SLEEP = 0.3
SSR_SET_SLEEP = 0.05
BOX_SET_SLEEP = 0.01
ACQ_TIMEOUT = 10
PRE_TRIG_SAMPLES = 0
POST_TRIG_SAMPLES = 1
BYTES_PER_SAMPLE = 2
TRIG_TIMETAG_BYTES = 16
def open_all_channels(fmc):
for i in range(1,NB_CHANNELS+1):
fmc.set_input_range(i, 'OPEN')
time.sleep(SSR_SET_SLEEP)
def fmc_adc_init(fmc):
print "Initialise FMC board:\n reset dc offset DACs\n open all channels\n config trigger: software"
# Reset offset DACs
fmc.dc_offset_reset()
# Make sure all switches are OFF
open_all_channels(fmc)
# Set software trigger
fmc.set_soft_trig()
# Set acquisition
fmc.set_pre_trig_samples(PRE_TRIG_SAMPLES)
fmc.set_post_trig_samples(POST_TRIG_SAMPLES)
# Converts two's complement hex to signed
def hex2signed(value):
if(value & 0x8000):
return -((~value & 0xFFFF) + 1)
else:
return value
# Converts digital value to volts
def digital2volt(value, full_scale, nb_bit):
return float(value) * float(full_scale)/2**nb_bit
def make_acq(fmc, pause, shots=1):
# Make sure no acquisition is running
fmc.stop_acq()
time.sleep(pause)
# Start acquisition
fmc.start_acq()
# Trigger
for i in range(shots):
time.sleep(pause)
fmc.sw_trig()
#print("Trigger %d"%i)
# Wait end of acquisition
timeout = 0
while('IDLE' != fmc.get_acq_fsm_state()):
time.sleep(.1)
timeout += 1
if(ACQ_TIMEOUT < timeout):
print "Acquisition timeout. Missing trigger?."
print "Acq FSm state: %s"%fmc.get_acq_fsm_state()
return fmc.get_trig_pos()
def get_acq_data(fmc, start_addr, data_length):
channels_data = fmc.get_data(start_addr, data_length)
return channels_data
def main (default_directory='.'):
# Constants declaration
LUN = 0
TEST_NB = 37
FMC_ADC_BITSTREAM = '../../../../../firmwares/svec_fmcadc100m14b4cha.bin'
FMC_ADC_BITSTREAM = os.path.join(default_directory, FMC_ADC_BITSTREAM)
EXPECTED_BITSTREAM_TYPE = 0x0
error = 0
start_test_time = time.time()
print "================================================================================"
print "Test%02d start\n" % TEST_NB
# SVEC object declaration
print "Loading hardware access library and opening device.\n"
bus = VME_rr_compatible(LUN)
print "Initialising device.\n"
bus.vv_init()
# Load FMC ADC firmware
print "Loading FMC ADC firmware: %s\n" % FMC_ADC_BITSTREAM
ret = bus.vv_load(FMC_ADC_BITSTREAM, 1)
print('')
time.sleep(2)
# Carrier object declaration (SVEC board specific part)
# Used to check that the firmware is loaded.
try:
carrier = CFmcAdc100mSvec(bus, EXPECTED_BITSTREAM_TYPE)
except FmcAdc100mSvecOperationError as e:
raise PtsCritical("Carrier init failed, test stopped: %s" % e)
# Mezzanines object declaration (FmcAdc100m14b4cha board specific part)
"""
fmc = []
for i in range(2):
try:
print('\n-------------------------------------------------------------')
print('[FMC slot %d]'%(i+1))
mezz_offset = 0x2000+i*0x4000
print('Mezzanine offset: 0x%08X'%(mezz_offset))
fmc.append(CFmcAdc100m(bus, mezz_offset))
except FmcAdc100mOperationError as e:
raise PtsCritical("Mezzanine %d init failed, test stopped: %s" % (i+1, e))
"""
try:
print('\n-------------------------------------------------------------')
print('[FMC slot 1]')
mezz_offset = 0x2000
print('Mezzanine offset: 0x%08X'%(mezz_offset))
fmc = (CFmcAdc100m(bus, mezz_offset))
except FmcAdc100mOperationError as e:
raise PtsCritical("Mezzanine 1 init failed, test stopped: %s" % (e))
try:
# Initialise fmc adc
fmc_adc_init(fmc)
# Use test data instead of data from ADC
# fmc.test_data_en()
# Use data pattern instead of ADC data
# fmc.testpat_en(0x2000)
# Set UTC
current_time = time.time()
utc_seconds = int(current_time)
fmc.set_utc_second_cnt(utc_seconds)
utc_coarse = int((current_time - utc_seconds)/8E-9)
fmc.set_utc_coarse_cnt(utc_coarse)
print("\nUTC core initialisation:\n seconds counter: 0x%08X\n coarse counter: 0x%08X" %(fmc.get_utc_second_cnt(), fmc.get_utc_coarse_cnt()))
# Acquisition parameters
ACQ_PAUSE = 1 # pause between acq. stop and start, start and trigger
IN_RANGE = '100mV'
IN_TERM = 'ON'
ADC_FS = {'10V':10.0, '1V':1.0, '100mV':0.1}
print("\nAnalog inputs config:\n termination: %s\n range: %s"%(IN_TERM, IN_RANGE))
for ch in range(NB_CHANNELS):
# Configure analogue input
fmc.set_input_range(ch+1, IN_RANGE)
fmc.set_input_term(ch+1, IN_TERM)
time.sleep(SSR_SET_SLEEP)
######################################################################################
# Single shot
print("\n\n--------------------------------------------------")
print("Single shot")
NB_SHOTS = 1
fmc.set_shots(NB_SHOTS)
print("\nAcquisition config:\n shots: %d\n pre-trigger: %d\n post-trigger: %d"%(NB_SHOTS, PRE_TRIG_SAMPLES, POST_TRIG_SAMPLES))
# Perform acquisition and retrieve data from DDR
trig_pos = make_acq(fmc, ACQ_PAUSE, NB_SHOTS)
print("Trigger position: 0x%08X"%(trig_pos))
data_length = ((PRE_TRIG_SAMPLES + 1 + POST_TRIG_SAMPLES) * NB_CHANNELS * BYTES_PER_SAMPLE) + TRIG_TIMETAG_BYTES
start_addr = (trig_pos-(PRE_TRIG_SAMPLES*8))
acq_data = get_acq_data(fmc, start_addr, data_length)
# Extract trigger timetag from data
# timetag = 4x 32-bit words
# acq_data is 16-bit wide -> last 8 cells corresponds to the timetag
data_trig_tag = []
tmp_data = []
for i in range(8):
tmp_data.append(acq_data.pop(-1))
for i in range(7,0,-2):
data_trig_tag.append(((tmp_data[i-1] << 16) + tmp_data[i]))
print("\nNumber of acquired samples: %d"%(len(acq_data)/4))
# Get time-tags from registers
trig_tag = fmc.get_utc_trig_tag()
# Print timetags
print("")
print('Trigger time-tag (from reg) meta: 0x%08X seconds: 0x%08X coarse: 0x%08X fine: 0x%08X'%(trig_tag[0], trig_tag[1], trig_tag[2], trig_tag[3]))
print('Trigger time-tag (from data) meta: 0x%08X seconds: 0x%08X coarse: 0x%08X fine: 0x%08X'%(data_trig_tag[0], data_trig_tag[1], data_trig_tag[2], data_trig_tag[3]))
# Compare trigger timetag from data and from register
if trig_tag != data_trig_tag:
error += 1
print("\n ERROR ==> Trigger timetag from data and from register don't match! ###")
else:
print("\n OK ==> Trigger timetag from data and from register match!")
# Plot all channels
#plot_channels(acq_data, ADC_FS[IN_RANGE])
######################################################################################
# Multi-shot
print("\n\n--------------------------------------------------")
print("Multi-shot")
NB_SHOTS = 10
fmc.set_shots(NB_SHOTS)
print("\nAcquisition config:\n shots: %d\n pre-trigger: %d\n post-trigger: %d"%(NB_SHOTS, PRE_TRIG_SAMPLES, POST_TRIG_SAMPLES))
# Perform acquisition and retrieve data from DDR
make_acq(fmc, ACQ_PAUSE, NB_SHOTS)
shot_length = ((PRE_TRIG_SAMPLES + 1 + POST_TRIG_SAMPLES)*NB_CHANNELS*BYTES_PER_SAMPLE) + TRIG_TIMETAG_BYTES
data_length = shot_length * NB_SHOTS
start_addr = 0
print("\nMake acquisistion:\n shot length: %d\n data length: %d"%(shot_length, data_length))
acq_data = get_acq_data(fmc, start_addr, data_length)
# split data in shots
shot_data = []
shot_length = shot_length/2 # acq_data is a 16-bit word array
for shot in range(NB_SHOTS):
shot_start = (shot*shot_length)
shot_end = ((shot+1)*shot_length)
shot_data.append(acq_data[shot_start:shot_end])
print(" shot nb: %2d shot start: %5d shot end: %5d -> length: %d"%(shot, shot_start, shot_end-1, len(shot_data[-1])))
# Extract trigger timetag from data
# timetag = 4x 32-bit words
# acq_data is 16-bit wide -> last 8 cells corresponds to the timetag
print("\nExtract trigger timetags:")
shot_trig_tag = []
for shot in range(NB_SHOTS):
data_trig_tag = []
tmp_data = []
for i in range(8):
tmp_data.append(shot_data[shot].pop(-1))
for i in range(7,0,-2):
data_trig_tag.append(((tmp_data[i-1] << 16) + tmp_data[i]))
shot_trig_tag.append(data_trig_tag)
print(" nb shot %d: nb samples: %d"%(shot,len(shot_data[shot])/4))
# Get time-tags from registers
trig_tag = fmc.get_utc_trig_tag()
# Print all trigger timetags from data
print("")
for shot in range(NB_SHOTS):
print('Trigger time-tag (from data) meta: 0x%08X seconds: 0x%08X coarse: 0x%08X fine: 0x%08X'%
(shot_trig_tag[shot][0], shot_trig_tag[shot][1], shot_trig_tag[shot][2], shot_trig_tag[shot][3]))
print('Trigger time-tag (from reg) meta: 0x%08X seconds: 0x%08X coarse: 0x%08X fine: 0x%08X'%
(trig_tag[0], trig_tag[1], trig_tag[2], trig_tag[3]))
# Compare trigger timetag from data (last shot) and from register
if trig_tag != shot_trig_tag[-1]:
error += 1
print("\n ERROR ==> Trigger timetag from data and from register don't match! ###")
else:
print("\n OK ==> Trigger timetag from data and from register match!")
######################################################################################
# Make sure all switches are OFF
open_all_channels(fmc)
# Check if an error occured during frequency response test
if(error != 0):
raise PtsError('An error occured, check log for details.')
except(FmcAdc100mSvecOperationError, FmcAdc100mOperationError) as e:
raise PtsError("Test failed: %s" % e)
print ""
print "==> End of test%02d" % TEST_NB
print "================================================================================"
end_test_time = time.time()
print "Test%02d elapsed time: %.2f seconds\n" % (TEST_NB, end_test_time-start_test_time)
if __name__ == '__main__' :
main()
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