#!/usr/bin/env python2
# -*- coding: utf-8 -*-
#
# Copyright 2012-2015 Frédéric Magniette, Miguel Rubio-Roy, LLR
#
import pools,bindpyrame
import common_roc
import random,time,os
from re import search
dif_pool = pools.pool("dif")
#*************************** CONSTANTS ***********************************
#internal dif function array
modifier={}
modifier["GENFCMD"]=0x2c
modifier["READALL"]=0x1e
modifier["READSC"]=0x16
modifier["POWER"]=0x2
modifier["RESET"]=0x4
modifier["MODE"]=0x6
modifier["PWRPLS"]=0x8
modifier["SC"]=0xa
modifier["SCLOAD"]=0xc
modifier["RO"]=0xe
modifier["CTRLREG"]=0x10
modifier["READ_STATUS"]=0x12
modifier["RO_INFO"]=0x14
modifier["FPGAFW"]=0x18
modifier["SELCMDIN"]=0x1a
modifier["SPILL"]=0x1c
#TODO spread in code
fc={}
fc["RESET"]=0x21
fc["SPILL_START"]=0x42
fc["SPILL_STOP"]=0x62
fc["INT_START"]=0x22
fc["READOUT_STOP"]=0x23
fc["READOUT_CONT"]=0x43
fc["LINK_RESUME"]=0x6f
fc["LINK_PAUSE"]=0x8f
#*********************** GENERIC INTERNAL FUNCTIONS ************************
def load_file(filename):
# load a bitstream file and return it as a string
bitstream=""
try:
fd=open(filename,"r")
except:
return 0,"cant open file %s"%(filename)
try:
bitstream=fd.read()
except:
return 0,"cant read file %s"%(filename)
fd.close()
return 1,bitstream
def calc_mask(dif):
# compute the mask value derived from port number and used in several commands
return "%d" % 2**(int(dif["gdcc_port"])-1)
def print_difwd(string,pos):
# uncap a dif data string and return it as an hexa string
return "0x%s%s"%(string[pos+2:pos+4],string[pos+0:pos+2])
def difwd(string,pos):
# uncap a dif data string and return it as an integer
return int("0x%s%s"%(string[pos+2:pos+4],string[pos+0:pos+2]),16)
def print_bin(x):
# print a 8 bits integer in binary
return ''.join(x & (1 << i) and '1' or '0' for i in range(7,-1,-1))
def print_sbin(x):
# print a 16 bits integer in binary
return ''.join(x & (1 << i) and '1' or '0' for i in range(15,-1,-1))
def print_bin_difwd(string,pos):
# display a dif data string
return "%s%s" % (print_bin(int(string[pos+2:pos+4],16)),print_bin(int(string[pos+0:pos+2],16)))
def split_data(string):
# format an integer array from a dif data string
result=[]
for i in range(0,len(string),4):
strval="0x%s%s%s%s"%(string[i+2],string[i+3],string[i],string[i+1])
result.append(int(strval,16))
return result
def prepare_data(inttab):
# format a dif packet string from an integer array
preresult=""
result=""
for i in range(len(inttab)):
low=inttab[i]&0xff
high=(inttab[i]&0xff00)>>8
preresult=preresult+"%02x%02x"%(low,high)
for i in range(0,len(preresult),2):
if i!=len(preresult)-2:
result=result+"0x%s%s,"%(preresult[i],preresult[i+1])
else:
result=result+"0x%s%s"%(preresult[i],preresult[i+1])
return result
def prepare_short(integer):
# prepare a short for dif packet format
high=integer&0xff
low=(integer&0xff00)>>8
return "0x%x,0x%x" % (high,low)
#******************************** GDCC CONNECTION FUNCTIONS ******************
def send_fc(dif,fcnum):
# send a fast command
print("send_fc %s"%(str(fcnum)))
retcode,res=submod_execcmd("send_diffc@gdcc",dif["gdcc_id"],calc_mask(dif),str(fcnum))
if retcode==0:
return 0,"error in send_diffc_gdcc <- %s" % (res)
return retcode,res
def send_btcmd(dif,cmd,param):
# send a block transfer command
print("send_btcmd %s %s"%(cmd,param))
pktid=random.randrange(100,65534,1)
data=[2,pktid,modifier[cmd],1,int(param)]
prep_data=prepare_data(data)
#print("pktid=%x" % (pktid))
if modifier==0:
return 0,"cant send btcmd: unknwon command %s"%(cmd)
retcode,res=submod_execcmd("send_difpkt@gdcc",dif["gdcc_id"],dif["gdcc_port"],prep_data)
if retcode==0:
return 0,"cant send btcmd <- %s"%(res)
return 1,"0x%x"%(pktid)
#******************************** RAM1 INTERNAL FUNCTIONS ********************
def extract_sent_bitstream(ram_content,size):
# extract the good bytes of the ram to get the sent bitsream
ram=ram_content[4:2*size+4]
res=""
for i in range(size/2):
res+=ram[i*4:i*4+2]
return 1,res
#******************************* MODE INTERNAL FUNCTIONS ****************
def get_mode(dif):
# return the mode register of a dif as a str(list)
print("get_mode")
retcode,res=send_btcmd(dif,"MODE","1")
if retcode==0:
return 0,"cant read mode: %s" % (res)
pktid=res
retcode,res=submod_execcmd("get_cpkt_byid@acq","ecal_dif","0xd00d",pktid,"0","0")
if retcode==0:
return 0,"cant get response packet: %s" % (res)
mode=res[60:76]
frmver=int("0x"+mode[2:4]+mode[0:2],16)
channel=int("0x"+mode[6:8]+mode[4:6],16)
difid=int("0x"+mode[10:12]+mode[8:10],16)
bitmap=int("0x"+mode[14:16]+mode[12:14],16)
return 1,[bitmap,difid,channel,frmver]
def write_mode(dif,bitmap,difid,channel,frmver):
# write the mode register using the four variables given
print("write_mode %s %s %s %s"%(bitmap,difid,channel,frmver))
prepdata=prepare_data([1,0,6,4,frmver,channel,difid,bitmap])
retcode,res=submod_execcmd("send_difpkt@gdcc",dif["gdcc_id"],dif["gdcc_port"],prepdata)
if retcode==0:
return 0,"cant write mode: %s" % (res)
return 1,"mode written"
def set_difid(dif):
# set the difid in the dif mode register and verify the write
print("real set_difid %d"%(dif["difid"]))
#get the mode from dif
retcode,res=get_mode(dif)
if retcode==0:
return 0,"cant get mode values: %s"%(res)
bitmap,difid,channel,frmver=res
#write the mode with the new difid
retcode,res=write_mode(dif,bitmap,dif["difid"],channel,frmver)
if retcode==0:
return 0,"cant set difid packet: %s"%(res)
#get the mode to check
retcode,res=get_mode(dif)
if retcode==0:
return 0,"cant get mode values: %s"%(res)
bitmap,difid,channel,frmver=res
#verify the value
if dif["difid"]!=int(difid):
return 0,"the difid in dif (%d) is different needed difid (%d)"%(int(difid),dif["difid"])
dif["stream_id"]=dif["difid"]-1
return 1,"ok"
def set_mode_bit(dif,bit,value):
# set a specific bit in the mode bitmap register
falseval=2**int(bit)
trueval=(~falseval)&0xffff
retcode,res=get_mode(dif)
if retcode==0:
return 0,"cant get mode values: %s"%(res)
bitmap,difid,channel,frmver=res
if value=="0":
bitmap=bitmap|falseval
elif value=="1":
bitmap=bitmap&trueval
else:
return 0,"unknown value: %s"%(value)
retcode,res=write_mode(dif,bitmap,difid,channel,frmver)
if retcode==0:
return 0,"cant set power pulsing: %s"%(res)
return 1,"power pulsing setted"
[docs]def set_mode_bit_dif(dif_id,bit,value):
"""set a specific bit in the mode register of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,"dif_%s"%(str(e))
return set_mode_bit(dif,bit,value)
def verify_mode_bit(dif,bit,expvalue):
# verify the value of a bit in the mode bitmap register
retcode,res=get_mode(dif)
if retcode==0:
return 0,"cant get mode values: %s"%(res)
bitmap,difid,channel,frmver=res
if ((bitmap&(2**bit))>>bit)==expvalue:
return 1,"bitmap has expected value"%(res)
else:
return 0,"bit %s has not expected value"%(bit)
def set_sort_readout(dif,active):
# activate or inactivate the readout sorting
if active=="false":
retcode,res=set_mode_bit(dif,"14","1")
elif active=="true":
retcode,res=set_mode_bit(dif,"14","0")
else:
return 0,"unknown sort_readout value: %s"%(active)
if retcode==0:
return 0,"cant set readout sorting: %s"%(res)
return 1,"ok"
[docs]def set_sort_readout_dif(dif_id,active):
"""(des)activate the readout sorting of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
return set_sort_readout(dif,active)
def set_pwrpls(dif,active):
# activate or inactivate the power pulsing
if active=="false":
retcode,res=set_mode_bit(dif,"5","0")
elif active=="true":
retcode,res=set_mode_bit(dif,"5","1")
else:
return 0,"unknown pwrpls value: %s"%(active)
if retcode==0:
return 0,"cant set power pulsing: %s"%(res)
return 1,"ok"
[docs]def set_pwrpls_dif(dif_id,active):
"""(des)activate the power pulsing alimentation of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
return set_pwrpls(dif,active)
def set_alim_mode(dif,alim_mode):
# Set the alimentation mode of dif: CC for continuous current, PP for power pulsing
if alim_mode=="CC":
retcode,res=set_pwrpls(dif,"false")
if retcode==0:
return 0,"cant set alim mode %s" % (res)
elif alim_mode=="PP":
retcode,res=set_pwrpls(dif,"true")
if retcode==0:
return 0,"cant set alim mode %s" % (res)
else:
return 0,"unknown alim mode %s" % (alim_mode)
dif["alim"]=alim_mode
return 1,"ok"
[docs]def set_alim_mode_dif(dif_id,alim_mode):
"""Set the alimentation mode of dif: CC for continuous current, PP for power pulsing"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
return set_alim_mode(dif,alim_mode)
#******************************** BORB INTERNAL FUNCTIONS **************
def read_borb(dif,borbid):
# return the content of any borb register
print("read_borb %s"%(borbid))
borbnb=str(2**(int(borbid)-1))
retcode,res=send_btcmd(dif,"SPILL",borbnb)
if retcode==0:
return 0,"dif cant read borb: %s" %(res)
pktid=res
retcode,res=submod_execcmd("get_cpkt_byid@acq","ecal_dif","0xd00d",pktid,"0","0")
if retcode==0:
return 0,"cant read borb: %s" % (res)
return 1,res[60:]
def write_borb(dif,borbid,prepared_data):
# write the borb register
print("write_borb %s with %s"%(borbid,prepared_data))
borbcode=0x10+int(borbid)
data=prepare_data([3,0,borbcode,4])+","+prepared_data
retcode,res=submod_execcmd("send_difpkt@gdcc",dif["gdcc_id"],dif["gdcc_port"],data)
if retcode==0:
return 0,"cant write to borb %s: %s" % (borbid,res)
return 1,"write successful"
def get_btype(mode):
if mode=="BT":
btype=64
elif mode=="BCLK":
btype=128
elif mode=="BTBCLK":
btype=128+64
else:
btype=0 #ILC
print("btype=%d"%(btype))
return btype
def set_borb1(dif,mode):
# set the value of borb1 with roc values
print("set_borb1 mode=%s active_rocs=%d roc_type=%s"%(mode,dif["nb_active_rocs"],dif["roc_type"]))
btype=get_btype(mode)
ctype=0
if dif["roc_type"]=="skiroc":
ctype=0x30
elif dif["roc_type"]=="easiroc":
ctype=0x80
elif dif["roc_type"]=="spiroc2":
ctype=0x21
elif dif["roc_type"]=="spiroc2a":
ctype=0x23
elif dif["roc_type"]=="spiroc2b":
ctype=0x24
elif dif["roc_type"]=="spiroc2d":
ctype=0x26
elif dif["roc_type"]=="maroc3":
ctype=0x90
else:
return 0,"unknown chip type: %s"%(dif["roc_type"])
prep_data=prepare_data([ctype,btype,0,dif["nb_active_rocs"]])
return write_borb(dif,"1",prep_data)
def get_chiptype(dif):
# get the chiptype from borb1
retcode,res=read_borb(dif,"1")
if retcode==0:
return 0,"cant get borb1: %s"%(res)
return 1,str(difwd(res,0))
def set_dif_mode(dif,mode):
# set the running *mode* of the dif: BT for beam test mode, BTBCLK for beam test beam clock mode, BCLK for beam clock mode or ILC
print("set_dif_mode %s"%(mode))
retcode,res=read_borb(dif,"1")
if retcode==0:
return 0,"cant get borb1: %s"%(res)
ctype=difwd(res,0)
nb_chips=difwd(res,12)
btype=get_btype(mode)
prep_data=prepare_data([ctype,btype,0,nb_chips])
retcode,res=write_borb(dif,"1",prep_data)
if retcode==0:
return 0,res
#apply changes to dif config and cmod
dif["mode"]=mode
return 1,"ok"
[docs]def set_dif_mode_dif(dif_id,mode):
"""set the running *mode* of the dif: BT for beam test mode, BTBCLK for beam test beam clock mode, BCLK for beam clock mode or ILC"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,"dif_%s"%str(e)
return set_dif_mode(dif,mode)
#*********************** DEBUG EXTERNAL FUNCTIONS ************************
[docs]def send_fc_dif(dif_id,fcnum):
"""send a fast command to a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,"dif_%s"%str(e)
retcode,res=send_fc(dif,fcnum)
if retcode==0:
return 0,"error sending fast command: %s"%(res)
return retcode,res
[docs]def send_btcmd_dif(dif_id,cmd,param):
"""send a block transfer command the a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,"dif_%s"%(str(e))
retcode,res=send_btcmd(dif,cmd,param)
if retcode==0:
return 0,"cant send btcmd: %s" % (res)
pktid=res
retcode,res=submod_execcmd("get_cpkt_byid@acq","ecal_dif","0xd00d",pktid,"0","0")
if retcode==0:
return 0,"cant read resulti <- %s" % (res)
return 1,res[60:]
#*********************** INIT FUNCTIONS ************************
[docs]def init_dif(dif_id,parent,gdcc_port,dcc_nibble,ref,cnh,bxpn_thresh,plane_thresh,min_energy,spill_period,bx_period,mapping_filename,plan,offset_x,offset_y,offset_z,simul):
"initialize a dif"
difid = dif_pool.length() + 1
dif_pool.new(dif_id,
{"name":dif_id,
"gdcc_id":parent,
"gdcc_port":gdcc_port,
"dcc_nibble":dcc_nibble,
"difid":difid, # difid sent to hardware
"roc_type":"",
"nb_active_rocs":0,
"nb_rocs":0,
"ref":ref,
"cnh":cnh,
"bxpn_thresh":bxpn_thresh,
"plane_thresh":plane_thresh,
"min_energy":min_energy,
"spill_period":spill_period,
"bx_period":bx_period,
"mapping_filename":mapping_filename,
"plan":plan,
"offset_x":offset_x,
"offset_y":offset_y,
"offset_z":offset_z,
"simul":simul,
"asus_list":""})
return 1,"ok"
[docs]def start_converter_dif(dif_id):
"""Start converters for *dif_id*"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
streamid=str(int(dif["difid"])-1)
plugin_name="/opt/pyrame/"+dif["roc_type"]+"_decoder.so"
retcode,res=submod_execcmd("set_stream_name@acq","ecal_dif",streamid,dif["name"])
if retcode==0:
return 0,"dif : cant set stream name <- %s"%(res)
if os.path.exists(plugin_name):
if dif["roc_type"]=="skiroc":
#retcode,res=submod_execcmd("start_converter@acq","ecal_dif",streamid,plugin_name,dif["ref"],dif["cnh"],dif["bxpn_thresh"],dif["plane_thresh"],"0",dif["spill_period"],dif["bx_period"],dif["mapping_filename"],dif["plan"],dif["offset_x"],dif["offset_y"],dif["offset_z"],str(dif["nb_rocs"]))\
retcode,res=submod_execcmd("start_converter@acq","ecal_dif",streamid,plugin_name,dif["ref"],"0",dif["bxpn_thresh"],dif["plane_thresh"],"0",dif["spill_period"],dif["bx_period"],dif["mapping_filename"],dif["plan"],dif["offset_x"],dif["offset_y"],dif["offset_z"],str(dif["nb_rocs"]))
if dif["roc_type"]=="spiroc2d":
retcode,res=submod_execcmd("start_converter@acq","ecal_dif",streamid,plugin_name,streamid,dif["ref"],dif["cnh"],dif["min_energy"],dif["mapping_filename"],dif["offset_x"],dif["offset_y"],"20")
if retcode==0:
return 0,"dif : cant start converter <- %s"%(res)
else:
print("warning : no plugin for %s roc type"%(dif["roc_type"]))
return 1,"ok"
[docs]def init_fin_dif(dif_id):
"""Finalize initialization after processing of ASU and DIFs"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
retcode,res=submod_execcmd("get_name_sublist@cmod","asu",dif_id)
if retcode==0 or res=="":
return 0,"error while getting ASUs of DIF %s <- %s"%(dif["name"],res)
asus=res.split(",")
roc_types=[]
asus_list=[]
for asu_id in asus:
asus_list.append(asu_id)
retcode,res=submod_execcmd("get_nb_active_rocs@asu",asu_id)
if retcode==0:
return 0,"cant get number of active ROCS on asu_id %s <- %s"%(asu_id,res)
dif["nb_active_rocs"]+=int(res)
retcode,res=submod_execcmd("get_nb_rocs@asu",asu_id)
if retcode==0:
return 0,"cant get number of ROCS on asu_id %s <- %s"%(asu_id,res)
dif["nb_rocs"]+=int(res)
retcode,res=submod_execcmd("get_roc_type@asu",asu_id)
if retcode==0:
return 0,"error getting roc_type of asu_id %s <- %s"%(asu_id,res)
if res not in roc_types:
roc_types.append(res)
if len(roc_types)>1:
return 0,"%s has ASUs with different ROC types"%(dif["name"])
dif["roc_type"]=roc_types[0]
dif["asus_list"]=",".join(asus_list)
return 1,"ok"
[docs]def deinit_dif(dif_id):
"deinitialize dif"
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 1,str(e)
dif_pool.remove(dif_id)
return 1,"ok"
def config_once(dif):
# real configuration of the dif: reset, set the mode, set the alimentation mode
#reset the dif fifo by sending a spill
print("reset dif fifo")
retcode,res=send_fc(dif,0x42) #start spill
if retcode==0:
return 0,"cant reset dif: %s" % (res)
time.sleep(0.1)
retcode,res=send_fc(dif,0x62) #stop spill
if retcode==0:
return 0,"cant reset dif: %s" % (res)
time.sleep(0.1)
#reset the dif registers
print("reset dif")
retcode,res=send_fc(dif,0x21)
if retcode==0:
return 0,"cant reset dif: %s" % (res)
time.sleep(0.1)
#set the dif id
print("set difid")
retcode,res=set_difid(dif)
if retcode==0:
return 0,"cant set difid %s" % (res)
time.sleep(0.1)
#set the mode (dif_mode) and the roc_type
print("set_mode %s"%(dif["mode"]))
retcode,res=set_borb1(dif,dif["mode"])
if retcode==0:
return 0,"cant set run mode %s" % (res)
time.sleep(0.1)
#set the alimentation mode CC or PP
retcode,res=set_alim_mode(dif,dif["alim_mode"])
if retcode==0:
return 0,res
time.sleep(0.1)
return 1,"ok"
[docs]def config_dif(dif_id,mode,alim):
"""configure the dif """
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
#store parameters
dif["mode"]=mode
dif["alim_mode"]=alim
#adapt the resilience to the config mode
retcode,res=submod_execcmd("getvar@varmod","varmod","ecal","config_mode")
if retcode==0:
print("cant get config_mode from varmod: going to debug mode")
nbtry=1
else:
if res=="debug":
nbtry=1
else:
nbtry=3
#configure the difs
if dif["simul"]=="0":
for i in range(nbtry):
print("iteration %d"%(i))
retcode,res=config_once(dif)
if retcode!=0:
break
if retcode==0:
return 0,"cant config: %s" % (res)
return 1,"dif %s configured" % (dif_id)
[docs]def config_fin_dif(dif_id):
"""Finalize configuration of dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
if dif["simul"]=="1":
return 1,"dif %s post-configured"%(dif_id)
#reset the probe of the rocs
retcode,res=reset_rocs_probe(dif)
if retcode==0:
return 0,"cant reset rocs probe: %s"%(res)
time.sleep(0.1)
#reset the slow control of the rocs
retcode,res=reset_rocs_sc(dif)
if retcode==0:
return 0,"cant reset rocs sc: %s"%(res)
time.sleep(0.1)
#send the bitstreams to the rocs
retcode,res=send_rocconfig(dif)
if retcode==0:
return 0,"cant send roc bitstreams: %s"%(res)
time.sleep(0.1)
return 1,"dif %s post-configured"%(dif_id)
[docs]def validate_dif(dif_id):
"""validate the configuration after any reconfiguration"""
try:
dif=dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
#reconfigure the dif
retcode,res=config_once(dif)
#reset the slow control of the rocs
retcode,res=reset_rocs_sc(dif)
if retcode==0:
return 0,"cant reset rocs sc: %s"%(res)
time.sleep(0.1)
#send the bitstreams to the rocs
retcode,res=send_rocconfig(dif)
if retcode==0:
return 0,"cant send roc bitstreams: %s"%(res)
time.sleep(0.1)
#return result
return 1,"ok"
[docs]def inval_dif(dif_id):
"""invalidate the dif configuration"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
return 1,"dif config invalidated"
#*********************** REGISTERS EXTERNAL FUNCTIONS ************************
[docs]def read_borb_dif(dif_id,borbid):
"""read and display the borb register of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
if int(borbid)>3 or int(borbid)<1:
return 0,"error borb number has to be in [1:3]"
retcode,res=read_borb(dif,borbid)
if retcode==0:
return 0,"cant read borb: %s" %(res)
if borbid=="1":
return 1,"\tROCREG0 rocint \t\t= %s\tROCREG3 mode \t\t= %s\tREG4 unused \t\t= %s\tROCREG3 chip nb \t= %s\t" % (print_difwd(res,0),print_difwd(res,4),print_difwd(res,8),print_difwd(res,12))
if borbid=="2":
return 1,"\tROCCMD \t\t= %s\t" % (print_difwd(res,0))
if borbid=="3":
return 1,"\tRND delay \t\t= %s\tRND enable \t\t= %s\tRND nbpkt\t\t= %s\tRND pktsize \t\t= %s\t" % (print_difwd(res,0),print_difwd(res,4),print_difwd(res,8),print_difwd(res,12))
[docs]def read_status_dif(dif_id):
"""read and display the status register of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
retcode,res=send_btcmd(dif,"READ_STATUS","1")
if retcode==0:
return 0,"cant read status: %s" % (res)
pktid=res
retcode,res=submod_execcmd("get_cpkt_byid@acq","ecal_dif","0xd00d",pktid,"0","0")
if retcode==0:
return 0,"cant read status: %s" % (res)
else:
return 1,"\tREG0 DIF state \t\t= %s\tREG1 RO state \t\t= %s\tREG2 SC state \t\t= %s\tREG3 BUFFER \t\t= %s\tREG4 QUEUE \t\t= %s\tREG5 Tout ramfull \t= %s\tREG6 Tout txon \t\t= %s\tREG7 Tout ro \t\t= %s\tREG8 Rx \t\t= %s\tREG9 Rx bad \t\t= %s\tREG10 Tx \t\t= %s\tREG11 RO FSM \t\t= %s\tREG12 NBPAUSE \t\t= %s\tREG13 NBOVF \t\t= %s\t" %(print_difwd(res,60),print_difwd(res,64),print_difwd(res,68),print_difwd(res,72),print_difwd(res,76),print_difwd(res,80),print_difwd(res,84),print_difwd(res,88),print_difwd(res,92),print_difwd(res,96),print_difwd(res,100),print_difwd(res,104),print_difwd(res,108),print_difwd(res,112))
def is_properly_configured(dif):
retcode,res=send_btcmd(dif,"READ_STATUS","1")
if retcode==0:
return 0,"cant read status: %s" % (res)
pktid=res
retcode,res=submod_execcmd("get_cpkt_byid@acq","ecal_dif","0xd00d",pktid,"0","0")
if retcode==0:
return 0,"cant read status: %s" % (res)
else:
if difwd(res,68)>>15==0:
return 1,"ok"
else:
return 0,"rocs not properly configured"
def is_properly_configured_dif(dif_id):
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
return is_properly_configured(dif)
[docs]def read_BTCstatus_dif(dif_id):
"""read and display the BTCstatus register of a dif to know if a block transfer command is finished or not"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
retcode,res=send_btcmd(dif,"READ_STATUS","2")
if retcode==0:
return 0,"cant read BTCstatus: %s" % (res)
pktid=res
retcode,res=submod_execcmd("get_cpkt_byid@acq","ecal_dif","0xd00d",pktid,"0","0")
if retcode==0:
return 0,"cant read BTCstatus: %s" % (res)
else:
return 1,"\tREG0 GENFCMD \t\t= %s\tREG1 READALL \t\t= %s\tREG2 READSC \t\t= %s\tREG3 POWER \t\t= %s\tREG4 RESET \t\t= %s\tREG5 MODE \t\t= %s\tREG6 PWRPLS \t\t= %s\tREG7 SC \t\t= %s\tREG8 SCLOAD \t\t= %s\tREG9 RO \t\t= %s\tREG10 CTRLREG \t\t= %s\tREG11 READ_STATUS \t= %s\tREG12 RO_INFO \t\t= %s\tREG13 FPGAFW \t\t= %s\tREG14 SELCMDIN \t\t= %s\tREG15 SPILL \t\t= %s\t" %(print_difwd(res,60),print_difwd(res,64),print_difwd(res,68),print_difwd(res,72),print_difwd(res,76),print_difwd(res,80),print_difwd(res,84),print_difwd(res,88),print_difwd(res,92),print_difwd(res,96),print_difwd(res,100),print_difwd(res,104),print_difwd(res,108),print_difwd(res,112),print_difwd(res,116),print_difwd(res,120))
[docs]def read_mode_dif(dif_id):
"""read and display the mode register of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
retcode,res=get_mode(dif)
if retcode==0:
return 0,"cant get mode values: %s" % (res)
bitmap,difid,channel,frmver=res
return 1,"REG0 bitmap\t\t= %s\t\tREG1 DIF_ID \t\t= %x\tREG2 CHANNEL \t\t= %x\t\tREG3 FRM_VER \t\t= %d" % (print_sbin(bitmap),difid,channel,frmver)
[docs]def set_difid_dif(dif_id):
"""set the difid in the mode register of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
return set_difid(dif)
[docs]def synchro_dif(dif_id):
"""set a dif in synchronisation mode: waiting for a trigger impulsion"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
retcode,res=send_btcmd(dif,"MODE",32768)
if retcode==0:
return 0,"cant go to synchro mode" % (res)
return 1,"dif ready for synchro from ccc"
#*********************** RAM1 FUNCTIONS ******************
def prepare_data_for_ram1(data): #data is a string in ascii quartets
# format a dif packet string acceptable for ram from a simple dif packet string
result=""
size=len(data)
for i in range(0,size,2):
result=result+"0x%s%s,0" % (data[i],data[i+1])
if i!=size-2:
result=result+","
return result
def enable_ram1(dif):
# enable the access to the ram1 of dif
print("enable_ram1")
retcode,res=send_btcmd(dif,"SC","1")
if retcode==1:
return 1,"ok"
return 0,"cant enable ram1: %s"%(res)
[docs]def enable_ram1_dif(dif_id):
"""enable the ram for external writing"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
return enable_ram1(dif)
def disable_ram1(dif):
# disable access to dif ram
print("disable_ram1")
retcode,res=send_btcmd(dif,"SC","0")
if retcode==0:
return 0,"cant disable ram1: %s"%(res)
return 1,"ok"
[docs]def disable_ram1_dif(dif_id):
"""disable the ram for external writing"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
return disable_ram1(dif)
def read_ram1(dif):
# return the content of the dif ram as a string
nbp=0
result=""
retcode,res=send_btcmd(dif,"RO","4096")
if retcode==0:
return 0,"cant read ram1: %s"%(res)
pktid=res
while retcode==1:
retcode,res=submod_execcmd("get_cpkt_byid@acq","ecal_dif","0xd00d",pktid,"0","0")
if retcode==1:
nbp+=1
result+=res[60:-4]
if nbp==0:
return 0,"cant read ram1: no response packet"
return 1,result
[docs]def read_ram1_dif(dif_id):
"""read the content of the ram of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
enable_ram1(dif)
retcode,res=read_ram1(dif)
if retcode==0:
return 0,res
nbpkt=res
disable_ram1(dif)
return 1,nbpkt
def write_ram1(dif,data):
# format and write data in the dif ram1
size=len(data) #data are in ascii quartet
#As the final string contain a byte per word, the final size is equal to the byte size i.e. size/2
prep_data=prepare_data([1,0,0xc,int(size/2)])+","+prepare_data_for_ram1(data)
retcode,res=submod_execcmd("send_difpkt@gdcc",dif["gdcc_id"],dif["gdcc_port"],prep_data)
if retcode==0:
return 0,"cant write to ram1 <- %s" % (res)
return 1,"ok"
[docs]def load_ram1_byfile_dif(dif_id,filename):
"""load a file in the ram of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
enable_ram1(dif)
retcode,res=load_file(filename)
if retcode==0:
return 0,"cant load file: %s"%(res)
bitstream=res.rstrip()
print("bitstream=%s"%(bitstream))
retcode,res=write_ram1(dif,bitstream)
if retcode==0:
return 0,res
disable_ram1(dif)
return 1,"ok"
#*********************** RANDOM GENERATORFUNCTIONS ******************
[docs]def set_rgen_dif(dif_id,delay,pktnb,pktsize):
"""set the random generator of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
data="3,0,0,0,0x13,0,4,0,"+prepare_short(int(delay))+",1,0,"+prepare_short(int(pktnb)-1)+","+prepare_short(int(pktsize))
retcode,res=submod_execcmd("send_difpkt@gdcc",dif["gdcc_id"],dif["gdcc_port"],data)
if retcode==0:
return 0,"cant set rgen <- %s"%(res)
return 1,"ok"
[docs]def stop_rgen_dif(dif_id):
"""stop the random generator of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
data="3,0,0,0,0x13,0,4,0,0,0,0,0,0,0,0,0"
retcode,res=submod_execcmd("send_difpkt@gdcc",dif["gdcc_id"],dif["gdcc_port"],data)
if retcode==0:
return 0,"cant stop rgen <- %s"%(res)
return 1,"ok"
#*********************** ROC FUNCTIONS *********************
def set_SC_selectbit(dif,value):
# select the command bit SC/Probe
print("set_SC_selectbit %s"%(value))
retcode,res=read_borb(dif,"1")
if retcode==0:
return 0,res
borb1=split_data(res)
if value=="1":
borb1[0]=borb1[0]|0x100
elif value=="0":
borb1[0]=borb1[0]&0xfeff
else:
return 0,"selectbit value must be 0 or 1"
nborb1=prepare_data(borb1)
retcode,res=write_borb(dif,"1",nborb1)
if retcode==0:
return 0,"cant write borb: %s"%(res)
return 1,"select_bit setted"
[docs]def set_SC_selectbit_dif(dif_id,value):
"set the slow control select bit of all rocs on a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
retcode,res=set_SC_selectbit(dif,value)
if retcode==0:
return retcode,res
return retcode,res
[docs]def set_roc_bitchain_dif(dif_id,chainid):
"""select the roc chainid: slow control or probe for loading"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
if chainid=="SC":
retcode,res=set_SC_selectbit(dif,"0")
elif chainid=="PROBE":
retcode,res=set_SC_selectbit(dif,"1")
else:
retcode=0
res="unknown bitchain: %s"%chainid
if retcode==0:
return retcode,res
return retcode,res
[docs]def load_probe_dif(dif_id):
"""load the rocs probe from the ram of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
retcode,res=set_SC_selectbit(dif,"1")
if retcode==0:
return 0,"cant set select bit: %s"%(res)
retcode,res=send_btcmd(dif,"SCLOAD","1")
if retcode==0:
return 0,"cant write ram1 to probe: %s"%(res)
return 1,"probe loaded"
def read_analog_probe(dif,shift):
#set the 3e mode word with shift
#get the mode from dif
retcode,res=get_mode(dif)
if retcode==0:
return 0,"cant get mode values: %s"%(res)
bitmap,difid,channel,frmver=res
#write the mode with the shift
retcode,res=write_mode(dif,bitmap,difid,int(shift),frmver)
if retcode==0:
return 0,"cant send mode packet: %s"%(res)
#send the analog probe btcmd which is named "POWER" (logically)
retcode,res=send_btcmd(dif,"POWER","1")
if retcode==0:
return 0,"cant send POWER btcmd: %s"%(res)
return 1,"ok"
def read_analog_probe_dif(dif_id,shift):
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
retcode,res=read_analog_probe(dif,shift)
if retcode==0:
return 0,"cant set analog probe: %s"%(res)
return 1,"ok"
#**************************** RESET ROCS *********************
def reset_rocs_sc(dif):
retcode,res=send_btcmd(dif,"RESET","1")
if retcode==0:
return 0,"cant reset rocs sc: %s"%(res)
return 1,"ok"
[docs]def reset_rocs_sc_dif(dif_id):
"""reset the roc slow control of every rocs of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
return reset_rocs_sc(dif)
def reset_rocs_probe(dif):
retcode,res=send_btcmd(dif,"RESET","2")
if retcode==0:
return 0,"cant reset rocs probe: %s"%(res)
return 1,"ok"
[docs]def reset_rocs_probe_dif(dif_id):
"""reset the probes of every rocs of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
return reset_rocs_probe(dif)
[docs]def reset_rocs_dif(dif_id):
"""reset every rocs of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
retcode,res=send_btcmd(dif,"RESET","4")
if retcode==0:
return 0,"cant reset rocs: %s"%(res)
return 1,"ok"
def get_rocconfig(dif):
sc_asu = []
# sc of each ASU
for asu_id in dif["asus_list"].split(","):
retcode,res=submod_execcmd("dump_sc@asu",asu_id)
if retcode==0:
return 0,"cant dump SC from asu_id %s: %s"%(asu_id,res)
sc_asu.append(res.split("%"))
sc = ""
for i in range(len(sc_asu[0])):
for j in range(len(sc_asu))[::1-2*(i%2)]:
sc += sc_asu[j][i]
# pad sc at the end so that it is has a length multiple of 8bit
sc += "0"*((8-len(sc)%8) if (len(sc)%8) else 0)
# convert to hexadecimal
return 1,common_roc.bin2hexa(sc)
def send_rocconfig(dif):
# send the configuration to every rocs of a dif
#open the ram1 access
enable_ram1(dif)
time.sleep(0.1)
#check if gdcc is ready for sending rocconfig
retcode,res=submod_execcmd("get_status@gdcc",dif["gdcc_id"])
if retcode==0:
return 0,"cant connect to gdcc %s <- %s"%(dif["gdcc_id"],res)
#Get slow control
retcode,res = get_rocconfig(dif)
if retcode==0:
return 0,res
sc = res
print("slow control: %s"%(sc))
sc_length = len(sc)/2 # in bytes
#write the sc of the rocs to the ram1 by blocks of 2048 bits = 256 Bytes
bloc_length = 256
for i in range(sc_length/bloc_length + (1 if sc_length%bloc_length else 0)):
#build the config block
sc_block = sc[i*2*bloc_length:(i+1)*2*bloc_length]
#write the block to ram1
retcode,res=write_ram1(dif,sc_block)
if retcode==0:
return 0,"cant write SC to ram: %s"%(res)
time.sleep(0.1)
#close the ram1 access
disable_ram1(dif)
time.sleep(0.1)
#ask the dif to load the bitstreams in rocs
retcode,res=send_btcmd(dif,"SCLOAD","1")
if retcode==0:
return 0,"cant load SC from ram to roc: %s" % (res)
time.sleep(0.1)
#we do it twice
retcode,res=send_btcmd(dif,"SCLOAD","1")
if retcode==0:
return 0,"cant load SC from ram to roc: %s"%(res)
time.sleep(0.2)
retcode,res=is_properly_configured(dif)
if retcode==0:
return 0,res
return 1,"SC loaded into ROCs"
[docs]def send_rocconfig_dif(dif_id):
"""send the configuration to every roc of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
return send_rocconfig(dif)
[docs]def save_rocconfig_dif(dif_id,filename):
"""save in a file the configuration of all the rocs of a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
#Get slow control
retcode,res = get_rocconfig(dif)
if retcode==0:
return 0,res
sc = res
try:
fd=open(filename,"w")
except:
return 0,"cant save rocconfig to %s (permissions)"%(filename)
try:
fd.write(sc)
finally:
fd.close()
return 1,"ok"
#*********************** FAST COMMAND FUNCTIONS *********************
[docs]def reset_dif(dif_id):
"""reset a dif"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
retcode,res=send_fc(dif,0x21)
if retcode==0:
return 0,"cant reset: %s" % (res)
return 1,"ok"
[docs]def acq_start_int_dif(dif_id):
"""start the acquisition on a dif with a fast command"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
retcode,res=send_fc(dif,0x22)
if retcode==0:
return 0,"cant start internal acquisition: %s" % (res)
return 1,"ok"
[docs]def acq_start_ext_dif(dif_id):
"""start the external acquisition on a dif with a fast command"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
retcode,res=send_fc(dif,0x42)
if retcode==0:
return 0,"cant start external acquisition: %s"%(res)
return 1,"acq ext started"
[docs]def acq_stop_dif(dif_id):
"""stop the acquisition on a dif with a fast command"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
retcode,res=send_fc(dif,0x62)
if retcode==0:
return 0,"cant stop acquisition: %s" % (res)
return 1,"ok"
[docs]def ro_stop_dif(dif_id):
"""Force stop of data read-out (FIFO not flushed)"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
retcode,res=send_fc(dif,0x23)
if retcode==0:
return 0,"cant stop ro: %s" % (res)
return 1,"ok"
[docs]def ro_cont_dif(dif_id):
"""Continue data read-out"""
try:
dif = dif_pool.get(dif_id)
except Exception as e:
return 0,str(e)
retcode,res=send_fc(dif,0x43)
if retcode==0:
return 0,"cant cont ro: %s" % (res)
return 1,"ok"