Commit f5d07351 authored by egousiou's avatar egousiou

temp storage of pts pythin tests

git-svn-id: http://svn.ohwr.org/fmc-tdc@83 85dfdc96-de2c-444c-878d-45b388be74a9
parent c0124fd7
#! /usr/bin/env python
# coding: utf8
# Copyright CERN, 2011
# Author: EGousiou <egousiou@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Import system modules
import sys
import time
import os
# Add common modules location tp path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
# Import common modules
from ptsexcept import *
import rr
# Import specific modules
import fmc_tdc
sys.path.append('../../../../fmc_delay/software/python/')
import fdelay_lib
"""
test02: Test Mezzanine EEPROM
"""
EEPROM_ADDR = 0x50
def main (default_directory='.'):
# Constants declaration
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM = '../firmwares/eva_tdc_for_v2.bit'
FMC_TDC_CHANNEL_NB = 5
# SPEC object declaration
spec = rr.Gennum()
###########################################################################
# TDC
###########################################################################
# Bind SPEC object to FMC TDC card
print "\n-----------------------------------------------------------------"
print "---------------------------- FMC TDC ---------------------------- "
print "------------------- Mezzanine I2C EEPROM test -------------------"
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)
print "\n_________________________Initialisations_________________________\n"
# Load FMC TDC firmware
print "Loading FMC Fine Delay firmware...",
spec.load_firmware(FMC_TDC_BITSTREAM)
time.sleep(2)
print "Firmware loaded!"
# TDC object declaration
tdc = fmc_tdc.CFMCTDC(spec)
#########################################################################
print "\n_____________________________I2C test____________________________\n"
# Scan FMC i2c bus
periph_addr = tdc.mezz_i2c_scan()
# Check that the EEPROM is detected on the I2C bus
if(0 == len(periph_addr)):
print"No peripheral detected on system management I2C bus"
else:
if(1 != len(periph_addr)):
print"Signal integrity problem detected on system management I2C bus, %d devices detected instead of 1"%(len(periph_addr))
else:
if(EEPROM_ADDR != periph_addr[0]):
print"Wrong device mounted on system management I2C bus, address is:0x%.2X expected:0x%.2X"%(periph_addr[0],EEPROM_ADDR)
# Write, read back and compare
addr = 0x20
wr_data = [0x55, 0xAA, 0x00, 0xFF]
rd_data = []
print('Writting data at EEPROM address 0x%.2X: ')%addr,
print wr_data
tdc.mezz_i2c_eeprom_write(addr, wr_data)
time.sleep(0.1)
print('Reading data from EEPROM address 0x%.2X:')%addr,
rd_data = tdc.mezz_i2c_eeprom_read(addr, len(wr_data))
print rd_data
if(rd_data != wr_data):
raise PtsError('/!\Cannot access EEPROM at address 0x%.2X/!\ '%(EEPROM_ADDR))
else:
print('\n!Data comparison OK!')
print "\n-----------------------------------------------------------------"
if __name__ == '__main__' :
main()
#! /usr/bin/env python
# coding: utf8
# Copyright CERN, 2011
# Author: EGousiou <egousiou@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Import system modules
import sys
import time
import os
import math
import termcolor
from termcolor import colored
# Add common modules location to path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
# Import common modules
from ptsexcept import *
import rr
# Import specific modules
import fmc_tdc
sys.path.append('../../../../fmc_delay/software/python/')
import fdelay_lib
"""
test04: Test the write pointer and the interrupts occurence
Use of FD board
2 TDC channels need to be receiving pulses
"""
def main (default_directory='.'):
# Constants declaration
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM = '../firmwares/eva_tdc_for_v2.bit'
FMC_TDC_CHANNEL_NB = 5
FMC_DELAY_ADDR = '1a39:0004/1a39:0004@0005:0000'
FMC_DELAY_BITSTREAM = '../firmwares/fmc_delay_spec.bin'
# SPEC object declaration
spec = rr.Gennum()
###########################################################################
# TDC
###########################################################################
# Bind SPEC object to FMC TDC card
print "-----------------------------------------------------------------"
print "---------------------------- FMC TDC ---------------------------- "
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)
# Load FMC TDC firmware
print "\n_________________________Initialisations_________________________\n"
print "Loading FMC TDC firmware...",
spec.load_firmware(FMC_TDC_BITSTREAM)
time.sleep(2)
print "Firmware loaded!"
# TDC object declaration
tdc = fmc_tdc.CFMCTDC(spec)
# TDC configuration
print "\n__________________________Configuration__________________________\n"
tdc.config_acam()
tdc.set_irq_tstamp_thresh(0x100) # set to max 256 tstamps
tdc.set_irq_time_thresh(0x10) # 16 secs
time.sleep(1)
tdc.enable_channels()
for ch in range(1,FMC_TDC_CHANNEL_NB+1):
tdc.channel_term(ch, 1)
print "\n___________________________ACAM reset____________________________\n"
tdc.reset_acam()
print "\n___________________________ACAM status___________________________\n"
acam_status_test = tdc.read_acam_status()-0xC4000800
if acam_status_test == 0:
print "ACAM status OK!"
else:
print "/!\ACAM not OK../!\ "
###########################################################################
# Fine Delay
###########################################################################
print "\n-----------------------------------------------------------------"
print "------------------------- FMC FINE DELAY ------------------------"
# 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)
# Load FMC Fine Delay firmware
print "\n\nLoading FMC Fine Delay firmware...",
sys.stdout.flush()
spec.load_firmware(FMC_DELAY_BITSTREAM)
time.sleep(2)
print "Firmware loaded!"
# Fine Delay object declaration
print "\n"
fdelay = fdelay_lib.FineDelay(spec.get_fd())
# 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 "\nFine Delay UTC time = %d, Coarse time = %d"%(fd_time.utc, fd_time.coarse)
# Configure the Fine Delay as a pulse generator
channel = 1 # must be 1, 2, 3 or 4
enable = 1 # this one is obvious
t_start_utc = fdelay.get_time().utc+4 # pulse(s) generation start time (-> 2 seconds in the future)
t_start_coarse = 0
width = 200000 # pulse width 200 ns
delta = 100000000000 # a pulse every 100 ms
count = 645 # 645 pulses on each channel = 2580 tstamps
fdelay.conf_pulsegen(channel, enable, t_start_utc, t_start_coarse, width, delta, count)
fdelay.conf_pulsegen(channel+1, enable, t_start_utc, t_start_coarse+50, width, delta, count)
###########################################################################
# TDC
###########################################################################
print "\n-----------------------------------------------------------------"
print "---------------------------- FMC TDC ---------------------------- "
# Bind SPEC object to FMC TDC card
spec.bind(FMC_TDC_ADDR)
print "\n___________________________ACAM status___________________________\n"
acam_status_test = tdc.read_acam_status()-0xC4000800
if acam_status_test == 0:
print "ACAM status OK!"
else:
print "/!\ACAM not OK../!\ "
print "\n_________________Reading back ACAM configuration_________________\n"
tdc.readback_acam_config()
# Enables TDC core interrupts
print "\n____________________________IRQ mask_____________________________\n"
print('Set IRQ enable mask: %.4X')%tdc.set_irq_en_mask(0xC)
print "\n_______________________Starting aquisition_______________________\n"
tdc.start_acq()
print "\n__________________________IRQs testing___________________________\n"
# An IRQ is raised every 256 timestamps or if >0 and < 256 timestamps have been
# accumulated and 8 secs have passed since the last IRQ.
# In this test in total 2580 timestaps should be registered by the FPGA.
# Therefore we are expecting 11 IRQs:
# 10 IRQs for the first 2560 timestamps
# 1 IRQ for the last 20, 8 secs after the 10th IRQ
# For the first 10, upon IRQ arrival the write pointer should be 0, indicating
# that 256 timestamps have been written.
# For the last IRQ the write pointer should be 320 which is the number of bytes
# for 20 128-bits-long timestamps
# ToDooo:put time exit!!!if more than 1 min has passed (in case irqs have not arrived, exit)
tdc_wr_ptr_list = []
tdc_overflow_list = []
irq_src_list = []
for i in range(11):
tdc.check_irq(0)
irq_src = tdc.get_irq_src()
print "IRQ iteration: %d // Overflows: %d // IRQ source: %d // Write pointer: %d \r"%(i, tdc.get_overflow_counter(), irq_src, tdc.get_pointer()),
sys.stdout.flush()
tdc.clear_irq_src(int(math.log(irq_src,2)))
irq_src_list.append(irq_src)
tdc_wr_ptr_list.append(tdc.get_pointer())
tdc_overflow_list.append(tdc.get_overflow_counter())
print "\nOverflow counter upon IRQ:",
print tdc_overflow_list
print "IRQ sources :",
print irq_src_list
print "Write pointer upon IRQ :",
print tdc_wr_ptr_list
if (tdc_wr_ptr_list == [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 320]) and (tdc_overflow_list == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10]) and (irq_src_list == [4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8]):
print ('\nIRQ test sucessful :)')
else:
print ('\n/!\IRQ test failed..:( ')
print "\n_______________________Stopping aquisition_______________________\n"
tdc.stop_acq()
print "\n-----------------------------------------------------------------\n\n\n"
if __name__ == '__main__' :
main()
#! /usr/bin/env python
# coding: utf8
# Copyright CERN, 2011
# Author: EGousiou <egousiou@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Import system modules
import sys
import time
import os
import math
import pylab
from pylab import *
from datetime import datetime
# Import common modules
from ptsexcept import *
import rr
# Import specific modules
import fmc_tdc
sys.path.append('../../../../fmc_delay/software/python/')
import fdelay_lib
# Add common modules location to path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
"""
test06: Tests the TDC precission: pulses are sent in 2 different channels with some delay between them introduced through a cable.
After thousands of pulses the span of all the measurements should remain <1000 ps.
Channel 1 of the FD board should arrive to any 2 channels of the TDC.
"""
def main (default_directory='.'):
# Constants declaration
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM = '../firmwares/eva_tdc_for_v2.bit'
FMC_TDC_CHANNEL_NB = 5
FMC_DELAY_ADDR = '1a39:0004/1a39:0004@0005:0000'
FMC_DELAY_BITSTREAM = '../firmwares/fmc_delay_spec.bin'
# SPEC object declaration
spec = rr.Gennum()
###########################################################################
# TDC
###########################################################################
# Bind SPEC object to FMC TDC card
print "test 06"
print "-----------------------------------------------------------------"
print "---------------------------- FMC TDC ---------------------------- "
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)
# Load FMC TDC firmware
print "\n_________________________Initialisations_________________________\n"
print "Loading FMC TDC firmware...",
spec.load_firmware(FMC_TDC_BITSTREAM)
time.sleep(2)
print "Firmware loaded!"
# TDC object declaration
tdc = fmc_tdc.CFMCTDC(spec)
# TDC configuration
print "\n__________________________Configuration__________________________\n"
tdc.config_acam()
tdc.set_irq_tstamp_thresh(0x100)
tdc.set_irq_time_thresh(0xFF)
time.sleep(1)
# Configuring DAC and PLL
#print "\n_____________________Configuring DAC and PLL_____________________\n"
#tdc.configure_mezz_dac(0xAA57) # nominal: xAA57, max: xFFFF, min: x0000
#time.sleep(2)
# Enable TDC channels and terminations
#for ch in range(1,FMC_TDC_CHANNEL_NB+1):
#tdc.channel_term(ch, 1)
tdc.enable_channels()
tdc.channel_term(1, 0)
tdc.channel_term(2, 1)
tdc.channel_term(3, 0)
tdc.channel_term(4, 1)
tdc.channel_term(5, 0)
# Check ACAM status
print "\n___________________________ACAM reset____________________________\n"
tdc.reset_acam()
print "\n___________________________ACAM status___________________________\n"
acam_status_test = tdc.read_acam_status()-0xC4000800
if acam_status_test == 0:
print "ACAM status OK!"
else:
print "/!\ACAM not OK../!\ "
# Readback all ACAM configuration regs
print "\n_________________Reading back ACAM configuration_________________\n"
tdc.readback_acam_config()
# Enable TDC core interrupts
# /!\ CAUTION!! /!\
# In this test we are not using interrupts as we have seen that when having two
# SPEC boards some interrupts may be missed after several iterations!!
#print "\n____________________________IRQ mask_____________________________\n"
#print('Set IRQ enable mask: %.4X')%tdc.set_irq_en_mask(0xC)
# Enable timestamps aquisition
print "\n_______________________Starting aquisition_______________________\n"
tdc.start_acq()
all_cable_delay_min = []
all_cable_delay_max = []
###########################################################################
# Fine Delay
###########################################################################
print "\n-----------------------------------------------------------------"
print "------------------------- FMC FINE DELAY ------------------------"
# 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)
# Load FMC Fine Delay firmware
print "\n\nLoading FMC Fine Delay firmware...",
sys.stdout.flush()
spec.load_firmware(FMC_DELAY_BITSTREAM)
time.sleep(2)
print "Firmware loaded!"
# Fine Delay object declaration
print "\n"
fdelay = fdelay_lib.FineDelay(spec.get_fd())
# 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 "\nFine Delay UTC time = %d, Coarse time = %d"%(fd_time.utc, fd_time.coarse)
# Configure the Fine Delay as a pulse generator
channel = 1 # must be 1, 2, 3 or 4
enable = 1 # this one is obvious
t_start_coarse = 0
width = 100000 # pulse width 100 ns
delta = 200000 # a pulse every 200 ns
count = 64 # 64 pulses on each channel; 256 timestamps
# File that keeps all the timestamps
all_raw_r_tstamps_file = open("all_raw_r_tstamps_008_ch2_4_fanout_newFD.txt","a")
all_cable_delay_file = open("all_cable_delay_008_ch2_4_fanout_newFD.txt","a")
all_temper_file = open("all_temper_008_ch2_4_fanout_newFD.txt","a")
# several iterations of sending pulses and retrieving timestamps
for m in range(500000):
print "\n\n>>Iteration:%d"%m
###########################################################################
# Fine Delay
###########################################################################
# Bind SPEC object to FMC Fine Delay card
spec.bind(FMC_DELAY_ADDR)
time.sleep(0.3) # was 0.5; somehow it's needed..otherwise after many iterations i get crushes!
# Configure the Fine Delay as a pulse generator
t_start_utc = fdelay.get_time().utc+1 # pulse(s) generation start time (-> 2 seconds in the future)
fdelay.conf_pulsegen(channel, enable, t_start_utc, t_start_coarse, width, delta, count)
print "\nFine Delay: %d pulses ready to be sent in 1 sec!"%count
###########################################################################
# TDC
###########################################################################
# Bind SPEC object to FMC TDC card
spec.bind(FMC_TDC_ADDR)
print "\n______________________TDC Precission testing_____________________\n"
#tdc.check_irq()
# /!\ CAUTION!! /!\
# In this test we are not using interrupts as we have seen that when having two
# SPEC boards some interrupts may be missed after several iterations!!
# a time.sleep statement is used instead!!
# In principle the TDC core memory is filled up with 256 timestamps,
# then they are retrieved through a DMA
# and then a new loop of sending and retrieving 256 new timestamps starts..
time.sleep(0.2)
print "The time now is: %s" %datetime.now()
temper = tdc.mezz_get_temp()
print "The temperature now is: %3.3f°C" %temper
all_temper_file.write("%s\n" %temper)
print "IRQ iteration: %d // Overflows: %d // IRQ source: %d // Write pointer: %d\n"%(m, tdc.get_overflow_counter(), tdc.get_irq_src(), tdc.get_pointer()),
timestamps, data = tdc.get_timestamps(0)
r_edge_timestamps = []
f_edge_timestamps = []
cable_delay_list = []
all_cable_delay_avg = []
for i in range(len(timestamps)):
if ((timestamps[i][2] == 1)):# and (timestamps[i][1] == 1 or timestamps[i][1] == 3)):
r_edge_timestamps.append(timestamps[i][0])
print "Number of r timestamps : %d"%(len(r_edge_timestamps))
for j in r_edge_timestamps:
all_raw_r_tstamps_file.write("%20.2f\n" %j)
r_edge_timestamps.sort()
for k in range(0,len(r_edge_timestamps),2):
cable_delay = r_edge_timestamps[k+1] - r_edge_timestamps[k]
cable_delay_list.append(cable_delay)
for l in cable_delay_list:
all_cable_delay_file.write("%20.2f\n" %l)
current_max = max(cable_delay_list)
current_min = min(cable_delay_list)
span = current_max-current_min
avg = (sum(cable_delay_list, 0.0) / len(cable_delay_list))
print "\nmax : %20.2f ps"%max(cable_delay_list)
print "min : %20.2f ps"%min(cable_delay_list)
print "span: %20.2f ps"%span
print "average: %20.2f ps"%avg
if span > 800:
print "Span messed up!"
all_cable_delay_max.append(current_max)
all_cable_delay_min.append(current_min)
all_cable_delay_avg.append(avg)
print "\nCurrent max: iteration %d, %20.2f ps"%(all_cable_delay_max.index(max(all_cable_delay_max)), max(all_cable_delay_max))
print "Current min: iteration %d, %20.2f ps"%(all_cable_delay_min.index(min(all_cable_delay_min)),min(all_cable_delay_min))
print "Current span: %20.2f ps"%((max(all_cable_delay_max))-(min(all_cable_delay_min)))
print "Current avg: %20.2f ps"%(sum(all_cable_delay_avg, 0.0) / len(all_cable_delay_avg))
# out of the for loop!
all_cable_delay_file.close()
all_temper_file.close()
all_raw_r_tstamps_file.close()
print "\n___________________________ACAM status___________________________\n"
acam_status_test = tdc.read_acam_status()-0xC4000800
if acam_status_test == 0:
print "ACAM status OK!"
else:
print "/!\ACAM not OK../!\ "
print "\n_________________Reading back ACAM configuration_________________\n"
tdc.readback_acam_config()
print "\n___________________________Statistics____________________________\n"
print all_cable_delay_min
print all_cable_delay_max
print "#### Final span: %20.2f ps ####"%((max(all_cable_delay_max))-(min(all_cable_delay_min)))
print "\n_______________________Stopping aquisition_______________________\n"
tdc.stop_acq()
print "\n-----------------------------------------------------------------\n\n\n"
if __name__ == '__main__' :
main()
#! /usr/bin/env python
# coding: utf8
# Copyright CERN, 2011
# Author: EGousiou <egousiou@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Import system modules
import sys
import time
import os
# Add common modules location to path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
# Import common modules
from ptsexcept import *
import rr
# Import specific modules
import fmc_tdc
sys.path.append('../../../../fmc_delay/software/python/')
import fdelay_lib
FAMILY_CODE = 0x28
"""
test01: Carrier One Wire
"""
def main (default_directory='.'):
# Constants declaration
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM = '../firmwares/eva_tdc_for_v2.bit'
FMC_TDC_CHANNEL_NB = 5
# SPEC object declaration
spec = rr.Gennum()
###########################################################################
# TDC
###########################################################################
# Bind SPEC object to FMC TDC card
print "\n-----------------------------------------------------------------"
print "---------------------------- FMC TDC ---------------------------- "
print "---------------------- Carrier 1 wire test ----------------------"
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)
print "\n_________________________Initialisations_________________________\n"
# Load FMC TDC firmware
print "Loading FMC TDC firmware...",
spec.load_firmware(FMC_TDC_BITSTREAM)
time.sleep(2)
print "Firmware loaded!"
# TDC object declaration
tdc = fmc_tdc.CFMCTDC(spec)
########################################################################
# Read unique ID and print to log
print "\n________________________Carrier unique ID________________________\n"
unique_id = tdc.carr_get_unique_id()
if(unique_id == -1):
print('/!\Cannot read DS18D20 1-wire thermometer/!\ ')
else:
print('Unique ID: %.12X') % unique_id
# Read temperatur and print to log
print "\n_______________________Carrier temperature_______________________\n"
temp = tdc.carr_get_temp()
print('Carrier temperature: %3.3f°C') % temp
if((unique_id & 0xFF) != FAMILY_CODE):
family_code = unique_id & 0xFF
print('family code: 0x%.8X') % family_code
print "\n-----------------------------------------------------------------"
if __name__ == '__main__' :
main()
#! /usr/bin/env python
# coding: utf8
# Copyright CERN, 2011
# Author: EGousiou <egousiou@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Import system modules
import sys
import time
import os
# Add common modules location to path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
# Import common modules
from ptsexcept import *
import rr
# Import specific modules
import fmc_tdc
sys.path.append('../../../../fmc_delay/software/python/')
import fdelay_lib
FAMILY_CODE = 0x28
"""
test01: Mezzanine One Wire
"""
def main (default_directory='.'):
# Constants declaration
FMC_TDC_ADDR = '1a39:0004/1a39:0004@000B:0000'
FMC_TDC_BITSTREAM = '../firmwares/eva_tdc_for_v2.bit'
FMC_TDC_CHANNEL_NB = 5
# SPEC object declaration
spec = rr.Gennum()
###########################################################################
# TDC
###########################################################################
# Bind SPEC object to FMC TDC card
print "\n-----------------------------------------------------------------"
print "---------------------------- FMC TDC ---------------------------- "
print "--------------------- Mezzanine 1 wire test ---------------------"
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)
print "\n_________________________Initialisations_________________________\n"
# Load FMC TDC firmware
print "Loading FMC TDC firmware...",
spec.load_firmware(FMC_TDC_BITSTREAM)
time.sleep(2)
print "Firmware loaded!"
# TDC object declaration
tdc = fmc_tdc.CFMCTDC(spec)
########################################################################
# Read unique ID and print to log
print "\n________________________Mezzanine unique ID______________________\n"
unique_id = tdc.mezz_get_unique_id()
if(unique_id == -1):
print('/!\Cannot read DS18D20 1-wire thermometer/!\ ')
else:
print('Unique ID: %.12X') % unique_id
# Read temperatur and print to log
print "\n_______________________Mezzanine temperature_____________________\n"
temp = tdc.mezz_get_temp()
print('Mezzanine temperature: %3.3f°C') % temp
if((unique_id & 0xFF) != FAMILY_CODE):
family_code = unique_id & 0xFF
print('family code: 0x%.8X') % family_code
print "\n-----------------------------------------------------------------"
if __name__ == '__main__' :
main()
#! /usr/bin/env python
# coding: utf8
# Copyright CERN, 2011
# Author: EGousiou <egousiou@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Import system modules
import sys
import time
import os
import math
import i2c
import onewire
import ds18b20
import eeprom_24aa64
# Add common modules location to path
sys.path.append('../../../')
sys.path.append('../../../gnurabbit/python/')
sys.path.append('../../../common/')
# Import common modules
import rr
from ptsexcept import *
import csr
import gn4124
"""
FMC TDC class
"""
class CFMCTDC:
# GNUM core WISHBONE adress
GNUM_CSR_ADDR = 0x0
# TDC core WISHBONE adress
TDC_CORE_ADDR = 0x20000
# IRQ controller
IRQ_CONTROLLER_ADDR = 0xA0000
IRQ_CTRL_SRC = 0x4
IRQ_CTRL_EN_MASK = 0x8
# Mezzanine I2C
MEZZ_I2C_ADDR = 0x60000
MEZZ_EEPROM_ADDR = 0x50
# Carrier One Wire
CARR_ONEWIRE_ADDR = 0x40000
# Mezzanine One Wire
MEZZ_ONEWIRE_ADDR = 0x80000
# ACAM register addresses
ACAM_READBACK_ADDR = [0x40, 0x44, 0x48, 0x4C, 0X50, 0x54, 0x58, 0x5C, 0x60, 0x64, 0x68, 0x6C, 0x70, 0x78]
# DMA length in bytes
DMA_LENGTH = 4096
# Write pointer register
WP_MASK = 0xFFF
WP_OVERFLOW_MASK = 0xFFFFF000
# Timestamp meta-data
META_CHANNEL_MASK = 0xF
META_SLOPE_MASK = 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.tdc_regs = csr.CCSR(self.bus, self.TDC_CORE_ADDR)
self.gnum = gn4124.CGN4124(self.bus, self.GNUM_CSR_ADDR)
self.irq_controller = csr.CCSR(self.bus, self.IRQ_CONTROLLER_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()
###############################################################################################
# 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)
# 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(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 "Configuring mezzanine DAC"
self.tdc_regs.wr_reg(0x98, dac_word)
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)
for i in self.ACAM_READBACK_ADDR:
print "reg 0x%02X = 0x%08X"%(i, self.tdc_regs.rd_reg(i))
# 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 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 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_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)
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()
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