Source code for cmd_dif

#!/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"