#!/usr/bin/env python import tango import logging import argparse import numpy as np import time ################################################################################################### # TANGO DEVICE PROXIES ################################################################################################### cellnode_subscribers = [ tango.DeviceProxy("ans/dg/fofb-cellnode-{}".format(cell)) for cell in ("C01", "C06", "C09", "C14") ] centralnode_subscriber = tango.DeviceProxy("ans/dg/fofb-centralnode") bpmmanager = tango.DeviceProxy("ans/dg/bpm-manager") fofbcommand = tango.DeviceProxy("ans/dg/fofb-command") ################################################################################################### # LOGGER ################################################################################################### # Install a BasicLogger logger = logging.getLogger("TestDev") sh=logging.StreamHandler() sh.setLevel(logging.DEBUG) sh.setFormatter(logging.Formatter("{levelname:8}: {message}", style='{')) ################################################################################################### # TANGO DB ATTRIBUTE CONFIG ################################################################################################### def set_attr_config(cnp): if "central" in cnp.name().lower(): set_attr_config_centralnode(cnp) else: set_attr_config_cellnode(cnp) def set_attr_config_cellnode(cnp): logger.info("Apply attribute configuration on device {}".format(cnp.name())) c = cnp.get_attribute_config("app_version") c.description = "FPGA firmware version\n" +c.description c.format = '0x%X' c.unit = ' ' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccneth0_gt_reset") c.description = "ComCellNode transceiver reset register, write 1 to reset.\n" +c.description c.format = '0x%X' c.unit = ' ' c.min_value='0' c.max_value='7' c.alarms.max_warning='1' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccneth0_reset") c.description = "ComCellNode data & serdes reset register, write 0xE0000001 to reset.\n" +c.description c.format = '0x%X' c.unit = ' ' c.min_value='0' c.alarms.max_warning='1' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccneth0_rx_framerate") c.description = "ComCellNode RX frame rate.\n" +c.description c.format = '%d' c.unit = 'fps' c.alarms.min_warning='10000' c.alarms.max_warning='11000' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccneth0_tx_framerate") c.description = "ComCellNode TX frame rate.\n" +c.description c.format = '%d' c.unit = 'fps' c.alarms.min_warning='10000' c.alarms.max_warning='11000' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccneth0_tx_errorrate") c.description = "ComCellNode TX erroneous frame rate.\n" +c.description c.format = '%d' c.unit = 'fps' c.alarms.max_warning='1' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccneth0_gt_status") c.description = "ComCellNode ethernet status. Expected value 0x70 or 0x71\n" +c.description c.format = '0x%X' c.unit = ' ' c.alarms.min_warning=str(0x6f) c.alarms.max_warning=str(0x72) cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnpack0_npackets") c.description = "ComCellNode number of packet to send -1. Usually 31 for C14 and 29 for others.\n" +c.description c.format = '%d' c.unit = 'packets' c.min_value='0' c.max_value='999' c.alarms.min_warning='28' c.alarms.max_warning='32' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnpack0_control") c.description = "ComCellNode packeter control, write 1 to start.\n" +c.description c.format = '0x%X' c.unit = ' ' c.min_value='0' c.max_value='1' c.alarms.min_warning='0' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnpack0_framesize") c.description = "ComCellNode output frame size. 330 for C14 else 310.\n" +c.description c.format = '%d' c.unit = 'bytes' c.min_value='0' c.max_value='999' c.alarms.min_warning='309' c.alarms.max_warning='331' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnpack0_error") c.description = "ComCellNode packeter protocol error flags.\n" +c.description c.format = '0x%X' c.unit = ' ' c.alarms.max_warning='1' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnpack0_framecount") c.description = "ComCellNode number of frame sent.\n" +c.description c.format = '%d' c.unit = 'frames' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnunpack0_framecount") c.description = "ComCellNode number of frame received.\n" +c.description c.format = '%d' c.unit = 'frames' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnunpack0_control") c.description = "ComCellNode unpacketer control, write 1 to start.\n" +c.description c.format = '0x%X' c.unit = ' ' c.min_value='0' c.max_value='1' c.alarms.min_warning='0' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnunpack0_error") c.description = "ComCellNode unpacketer protocol error flags.\n" +c.description c.format = '0x%X' c.unit = ' ' c.alarms.max_warning='1' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnunpack0_framesize") c.description = "ComCellNode input frame size. Usual value = 610.\n" +c.description c.format = '%d' c.unit = 'bytes' c.min_value='0' c.max_value='999' c.alarms.min_warning='609' c.alarms.max_warning='611' cnp.set_attribute_config(c) c = cnp.get_attribute_config("combpm_protocol_status") c.description = "ComCellNode ethernet status. Expected value 0x00\n" +c.description c.format = '0x%X' c.unit = ' ' c.alarms.max_warning='4' cnp.set_attribute_config(c) c = cnp.get_attribute_config("combpm_sfp") c.description = "ComBPM SFP status. Expected value 0x00\n" +c.description c.format = '0x%X' c.unit = ' ' c.alarms.max_warning='1' cnp.set_attribute_config(c) c = cnp.get_attribute_config("combpm_gt_status") c.description = "ComBPM transceiver status.\n" +c.description c.format = '0x%X' c.unit = ' ' cnp.set_attribute_config(c) c = cnp.get_attribute_config("combpm_valid_framerate") c.description = "ComBPM RX frame rate.\n" +c.description c.format = '%d' c.unit = 'fps' c.alarms.min_warning='1220000' c.alarms.max_warning='1230000' cnp.set_attribute_config(c) c = cnp.get_attribute_config("combpm_invalid_framecount") c.description = "ComBPM RX invalid frame rate. Should not increase to quickly (<1/s)\n" +c.description c.format = '%d' c.unit = 'frames' cnp.set_attribute_config(c) c = cnp.get_attribute_config("combpm_frameseq") c.description = "ComBPM number of frames received -1 in last sequence.\n" +c.description c.format = '%d' c.unit = 'frames' c.alarms.min_warning='121' c.alarms.max_warning='123' cnp.set_attribute_config(c) c = cnp.get_attribute_config("combpm_reset") c.description = "ComBPM protocol reset register, write 1 to reset.\n" +c.description c.format = '0x%X' c.unit = ' ' c.min_value='0' c.max_value='1' c.alarms.max_warning='1' cnp.set_attribute_config(c) c = cnp.get_attribute_config("combpm_gt_control") c.description = "ComBPM transceiver reset register, 1 to enable, 5 to reset.\n" +c.description c.format = '0x%X' c.unit = ' ' c.min_value='0' c.max_value='7' c.alarms.min_warning='0' c.alarms.max_warning='2' cnp.set_attribute_config(c) def set_attr_config_centralnode(cnp): logger.info("Apply attribute configuration on device {}".format(cnp.name())) c = cnp.get_attribute_config("app_version") c.description = "FPGA firmware version\n" +c.description c.format = '0x%X' c.unit = ' ' cnp.set_attribute_config(c) for n in range(4): c = cnp.get_attribute_config("ccneth{}_gt_reset".format(n)) c.description = "ComCellNode transceiver reset register, write 1 to reset.\n" +c.description c.format = '0x%X' c.unit = ' ' c.min_value='0' c.max_value='7' c.alarms.max_warning='1' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccneth{}_reset".format(n)) c.description = "ComCellNode data & serdes reset register, write 0xE0000001 to reset.\n" +c.description c.format = '0x%X' c.unit = ' ' c.min_value='0' c.alarms.max_warning='1' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccneth{}_rx_framerate".format(n)) c.description = "ComCellNode RX frame rate.\n" +c.description c.format = '%d' c.unit = 'fps' c.alarms.min_warning='10000' c.alarms.max_warning='11000' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccneth{}_tx_framerate".format(n)) c.description = "ComCellNode TX frame rate.\n" +c.description c.format = '%d' c.unit = 'fps' c.alarms.min_warning='10000' c.alarms.max_warning='11000' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccneth{}_tx_errorrate".format(n)) c.description = "ComCellNode TX erroneous frame rate.\n" +c.description c.format = '%d' c.unit = 'fps' c.alarms.max_warning='1' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccneth{}_gt_status".format(n)) c.description = "ComCellNode ethernet status. Expected value 0x70 or 0x71\n" +c.description c.format = '0x%X' c.unit = ' ' c.alarms.min_warning=str(0x6f) c.alarms.max_warning=str(0x72) cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnpack{}_npackets".format(n)) c.description = "ComCellNode number of packet to send -1. Usual value 99.\n" +c.description c.format = '%d' c.unit = 'packets' c.min_value='0' c.max_value='999' c.alarms.min_warning='98' c.alarms.max_warning='100' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnpack{}_control".format(n)) c.description = "ComCellNode packeter control, write 1 to start.\n" +c.description c.format = '0x%X' c.unit = ' ' c.min_value='0' c.max_value='1' c.alarms.min_warning='0' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnpack{}_framesize".format(n)) c.description = "ComCellNode output frame size. Usual value 610.\n" +c.description c.format = '%d' c.unit = 'bytes' c.min_value='0' c.max_value='999' c.alarms.min_warning='609' c.alarms.max_warning='611' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnpack{}_error".format(n)) c.description = "ComCellNode packeter protocol error flags.\n" +c.description c.format = '0x%X' c.unit = ' ' c.alarms.max_warning='1' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnpack{}_framecount".format(n)) c.description = "ComCellNode number of frame sent.\n" +c.description c.format = '%d' c.unit = 'frames' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnunpack{}_framecount".format(n)) c.description = "ComCellNode number of frame received.\n" +c.description c.format = '%d' c.unit = 'frames' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnunpack{}_control".format(n)) c.description = "ComCellNode unpacketer control, write 1 to start.\n" +c.description c.format = '0x%X' c.unit = ' ' c.min_value='0' c.max_value='1' c.alarms.min_warning='0' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnunpack{}_error".format(n)) c.description = "ComCellNode unpacketer protocol error flags.\n" +c.description c.format = '0x%X' c.unit = ' ' c.alarms.max_warning='1' cnp.set_attribute_config(c) c = cnp.get_attribute_config("ccnunpack{}_framesize".format(n)) c.description = "ComCellNode input frame size. 330 from C14 else 310.\n" +c.description c.format = '%d' c.unit = 'bytes' c.min_value='0' c.max_value='999' c.alarms.min_warning='309' c.alarms.max_warning='331' cnp.set_attribute_config(c) for p in "xy": c = cnp.get_attribute_config("corr_control_{}".format(p)) c.description = "Correction controller for {} plan. 1 is feedback running, 2 is reset correctors.\n".format(p.upper()) +c.description c.format = '0x%X' c.unit = ' ' c.min_value='0' c.max_value='2' cnp.set_attribute_config(c) c = cnp.get_attribute_config("corr_command_{}".format(p)) c.description = "Correction command sent for {} plan, in Ampers. Mobile mean on 1 second.\n".format(p.upper()) +c.description c.format = '%f' c.unit = 'A' cnp.set_attribute_config(c) c = cnp.get_attribute_config("orbit_error_{}".format(p)) c.description = "Orbit error read from BPMs, in nm. Mobile mean on 1 second.\n".format(p.upper()) +c.description c.format = '%d' c.unit = 'nm' cnp.set_attribute_config(c) c = cnp.get_attribute_config("corr_ref_{}".format(p)) c.description = "Orbit reference, in nm.\n".format(p.upper()) +c.description c.format = '%d' c.unit = 'nm' cnp.set_attribute_config(c) for n in "12": for cf in ("a","b","ic","d"): c = cnp.get_attribute_config("corr_k{}{}_{}".format(n,cf,p)) c.description = "Correction controller coefficient {}, filter {} plan\n".format(n,cf,p) +c.description c.format = '%d' c.unit = ' ' cnp.set_attribute_config(c) ################################################################################################### # OPERATION FUNCTIONS ################################################################################################### def cellnode_stop_ccn(cnp): logger.info("Stopping CCN on {}".format(cnp.name())) cnp["ccnpack0_control"] = False cnp["ccnunpack0_control"] = False def cellnode_start_ccn(cnp): logger.info("Starting CCN on {}".format(cnp.name())) cnp["ccneth0_reset"] = 0x60000001 # impossible to write 0xE0000001 cnp["ccneth0_gt_reset"] = 1 cnp["ccneth0_gt_reset"] = 0 cnp["ccneth0_reset"] = 0 cnp["ccnpack0_control"] = True cnp["ccnunpack0_control"] = True def cellnode_ack_ccn(snp): logger.info("Ack CCN error on {}".format(cnp.name())) cnp["ccnpack0_reset_error"] = True cnp["ccnunpack0_reset_error"] = True cnp["ccnpack0_reset_error"] = False cnp["ccnunpack0_reset_error"] = False def centralnode_stop_ccn(cnp): logger.info("Stopping CCN on {}".format(cnp.name())) for n in range(4): cnp["ccnpack{}_control".format(n)] = False cnp["ccnunpack{}_control".format(n)] = False def centralnode_start_ccn(cnp): logger.info("Starting CCN on {}".format(cnp.name())) for n in range(4): cnp["ccneth{}_reset".format(n)] = 0x60000001 # impossible to write 0xE0000001 cnp["ccneth{}_gt_reset".format(n)] = 1 cnp["ccneth{}_gt_reset".format(n)] = 0 cnp["ccneth{}_reset".format(n)] = 0 cnp["ccnpack{}_control".format(n)] = True cnp["ccnunpack{}_control".format(n)] = True cnp["ccnpack{}_reset_error".format(n)] = True cnp["ccnunpack{}_reset_error".format(n)] = True cnp["ccnpack{}_reset_error".format(n)] = False cnp["ccnunpack{}_reset_error".format(n)] = False def cellnode_configure_ccn(cnp, nbpm=None, npsc=100): """ Configure the ComCellNode block. PARAMETERS ---------- nbpm: Number of BPM allowed by the filter, hence the number of expected BPM packets. If None, auto detect the number from the combpm_filter_table attribute. npsc: Number of total PSC, hence the number of expected PSC packets. """ if nbpm is None: # Get number of BPM activated in the filter nbpm = int((cnp["combpm_filter_table"].value == 0x80).sum()) logger.debug("{} bpm allowed in the filter on {}".format(nbpm, cnp.name())) maclen = 10*nbpm+10 logger.debug("Configure packeter framesize (mac length) to {}".format(maclen)) cnp["ccnpack0_framesize"] = maclen logger.debug("Configure packeter npackets to {}".format(nbpm-1)) cnp["ccnpack0_npackets"] = nbpm-1 maclen = npsc*6+10 logger.debug("Configure unpacketer framesize (mac length) to {}".format(maclen)) cnp["ccnunpack0_framesize"] = maclen logger.info("Configuration of CCN done on {}.".format(cnp.name())) def centralnode_configure_ccn(cnp, nbpm=[30,30,30,32], npsc=100): """ Configure the ComCellNode block. PARAMETERS ---------- nbpm: list(int) Number of BPM packet received on each interface. npsc: Number of total PSC, hence the number of expected PSC packets. """ for n in range(4): maclen = npsc*6+10 logger.debug("Configure packeter {} framesize (mac length) to {}".format(n, maclen)) cnp["ccnpack{}_framesize".format(n)] = maclen logger.debug("Configure packeter {} npackets to {}".format(n, npsc-1)) cnp["ccnpack{}_npackets".format(n)] = npsc-1 maclen = 10*nbpm[n]+10 logger.debug("Configure unpacketer {} framesize (mac length) to {}".format(n, maclen)) cnp["ccnunpack{}_framesize".format(n)] = maclen logger.info("Configuration of CCN done on {}.".format(cnp.name())) def cellnode_stop_combpm(cnp): logger.info("Stopping ComBpm on {}".format(cnp.name())) cnp["combpm_reset"] = 1 cnp["combpm_gt_control"] = 0x5 def cellnode_start_combpm(cnp): logger.info("Starting ComBpm on {}".format(cnp.name())) cnp["combpm_reset"] = 0 cnp["combpm_gt_control"] = 0x1 cnp["combpm_reset_error"] = True cnp["combpm_reset_error"] = False def cellnode_configure_combpm(cnp): # Filter list depends on the cellnode filterlist = { "C01":np.array(list(range(1,23))+list(range(115,123))), "C06":np.array(range(23,53)), "C09":np.array(range(53,83)), "C14":np.array(range(83,115)), } for k in filterlist.keys(): if k in cnp.name(): logger.debug("Activate BPMs {} in the filter for {}".format(filterlist[k], cnp.name())) f = cnp["combpm_filter_table"].value f[:] = 0 f[np.array(filterlist[k])] = 0x80 cnp["combpm_filter_table"] = f logger.info("Configuration of ComBpm done on {}.".format(cnp.name())) def cellnode_configure_comcorr(cnp, enable=True): pscidlist = { 'C01':[50,100,49,99,255,255,255,255,2,52,1,51,255,255,255,255,56,6,3,53,4,54,5,55,10,60,7,57,8,58,9,59], 'C06':[12,62,11,61,255,255,255,255,14,64,13,63,255,255,255,255,68,18,15,65,16,66,17,67,22,72,19,69,20,70,21,71], 'C09':[24,74,23,73,255,255,255,255,26,76,25,75,255,255,255,255,80,30,27,77,28,78,29,79,34,84,31,81,32,82,33,83], 'C14':[36,86,35,85,37,87,38,88,40,90,39,89,255,255,255,255,94,44,41,91,42,92,43,93,48,98,45,95,46,96,47,97] } for k in pscidlist.keys(): if k in cnp.name(): logger.debug("Set PSCIDs {} in the filter for {}".format(pscidlist[k], cnp.name())) f= cnp["comcorr_line_id"].value f[:] = pscidlist[k] f[:] = f+ 0x10000*bool(enable) logger.debug("Set comcorr_line_id {} for {}".format(f, cnp.name())) cnp["comcorr_line_id"] = f logger.info("Configuration of ComCorr done on {}.".format(cnp.name())) def centralnode_configure_corr(cnp): # Legacy cnp["corr_k1a_x"]=256 cnp["corr_k1b_x"]=0 cnp["corr_k1ic_x"]=64 cnp["corr_k1d_x"]=16300 cnp["corr_k1a_y"]=256 cnp["corr_k1b_y"]=0 cnp["corr_k1ic_y"]=64 cnp["corr_k1d_y"]=16300 # Unitary cnp["corr_k2a_x"]=128 cnp["corr_k2b_x"]=0 cnp["corr_k2ic_x"]=8192 cnp["corr_k2d_x"]=0 cnp["corr_k2a_y"]=128 cnp["corr_k2b_y"]=0 cnp["corr_k2ic_y"]=8192 cnp["corr_k2d_y"]=0 f= cnp["corr_pscid"].value f[0:100] = range(1,101) cnp["corr_pscid"] = f logger.info("Configuration of Corr done on {}.".format(cnp.name())) def fofbcommand_writeref(what='current'): if what=="current": fofbcommand["x_ref_orbit"] = (bpmmanager.xmeanorbit*1e6).astype(int) fofbcommand["y_ref_orbit"] = (bpmmanager.zmeanorbit*1e6).astype(int) if what=="oldref": fofbcommand["x_ref_orbit"] = (bpmmanager.xreforbit*1e6).astype(int) fofbcommand["y_ref_orbit"] = (bpmmanager.zreforbit*1e6).astype(int) if what=="zeros": fofbcommand["x_ref_orbit"] = np.zeros(122, dtype=int) fofbcommand["y_ref_orbit"] = np.zeros(122, dtype=int) def fofbcommand_writemat(filename='respmat.npy'): fofbcommand["x_inv_resp_mat"] = np.hstack([np.zeros((50, 1)), np.load(filename)[50:], np.zeros((50,5))]).astype(int) fofbcommand["y_inv_resp_mat"] = np.hstack([np.zeros((50, 1)), np.load(filename)[:50], np.zeros((50,5))]).astype(int) ################################################################################################### # ################################################################################################### if __name__ == '__main__': parser = argparse.ArgumentParser("FofbTool") parser.add_argument("--log", default="info", help="Log level (error, warning, info, debug)") parser.add_argument("--init", action="store_true", help="Run init devices.") parser.add_argument("--confDS", action="store_true", help="Configure the Device servers, by applying attribute configuration.") parser.add_argument("--stop", action="store_true", ) parser.add_argument("--conf", action="store_true", ) parser.add_argument("--start", action="store_true", ) parser.add_argument("--disable-corr", action="store_true", help="Disable cellnode corrector output frames." ) parser.add_argument("--respmat", default=None, help="Configure response matrix from file" ) parser.add_argument("node", default="allnodes", nargs='*', choices=('c01', 'c06', 'c09', 'c14', 'central', 'allcells', 'allnodes'), help="Node to apply the selected actions. Default is all.") args = parser.parse_args() #### Install logger # Remove handler previously attached for hdlr in logger.handlers: logger.removeHandler(hdlr) # Attach this handler logger.addHandler(sh) # Set log level from args logger.setLevel(getattr(logging, args.log.upper())) #### logger.debug(args) #### Node selection nodes = [] if 'allnodes' in args.node: nodes = cellnode_subscribers + [centralnode_subscriber,] if 'allcells' in args.node: nodes = nodes + cellnode_subscribers if 'central' in args.node: nodes.append(centralnode_subscriber) if 'c01' in args.node: nodes.append(cellnode_subscribers[0]) if 'c06' in args.node: nodes.append(cellnode_subscribers[1]) if 'c09' in args.node: nodes.append(cellnode_subscribers[2]) if 'c14' in args.node: nodes.append(cellnode_subscribers[3]) nodes = list(set(nodes)) logger.debug("Perform actions on {}".format(nodes)) #### if args.init: for cnp in nodes: logger.info("Apply command init on {}".format(cnp.name())) cnp.init() if args.confDS: for cnp in nodes: set_attr_config(cnp) if args.stop: for cnp in cellnode_subscribers: cellnode_stop_ccn(cnp) cellnode_stop_combpm(cnp) centralnode_stop_ccn(centralnode_subscriber) if not args.respmat is None: centralnode_configure_respmat(centralnode_subscriber, args.respmat) if args.conf: for cnp in cellnode_subscribers: cellnode_configure_combpm(cnp) cellnode_configure_comcorr(cnp, not args.disable_corr) time.sleep(2) cellnode_configure_ccn(cnp) centralnode_configure_ccn(centralnode_subscriber) centralnode_configure_corr(centralnode_subscriber) elif args.disable_corr: for cnp in cellnode_subscribers: cellnode_configure_comcorr(cnp, not args.disable_corr) if args.start: for cnp in cellnode_subscribers: cellnode_start_ccn(cnp) cellnode_start_combpm(cnp) cellnode_ack_ccn(cnp) centralnode_start_ccn(centralnode_subscriber)