diff --git a/Scripts/pll_status_small.py b/Scripts/pll_status_small.py new file mode 100755 index 0000000000000000000000000000000000000000..c0e3628d5d3766ee8fb8c00cef020505a48eadb1 --- /dev/null +++ b/Scripts/pll_status_small.py @@ -0,0 +1,462 @@ +#!/usr/bin/python +""" + pll_status.py -- module to display pll status + + Author + JPC : 02/10/2018 + Eric Jules: 01/12/2018, adapt for Belle II +""" +import time +import os +import subprocess +import sys +import pathtocomponents +import curses + + +from fpga_comp import Arria10 +from si534x_comp import Si534x +from xcvr_comp import xcvr +from eepromat24c_comp import EepromAT24C +import addresses_comp as const + +def pll_window(pll, device, fpga, freq, conf, win): + + # SI5345_1 monitoring + # inputs + line = 2 + for j in range(0, 2): #was 4 + status, loss_of_signal = pll.read_loss_of_signal(j) + if conf[j] != "Not used": + win.addstr(line, 1, "Input " + str(j) + " : ",curses.A_BOLD) + if loss_of_signal == True: + win.addstr(line, 12,"Loss of signal ", RED) + else: + win.addstr(line, 12,"Input clock present", GREEN) + status, oof = pll.read_out_of_frequency(j) + # if oof == True: + # win.addstr(line + 1, 12,"Out of frequency ", RED) + #else: + # win.addstr(line + 1, 12,"Nominal frequency ", GREEN) + status, loss_of_signal_flg = pll.read_loss_of_signal_flg(j) + if loss_of_signal_flg == True: + win.addstr(line, 32, "LOS seen ", RED) + else: + win.addstr(line, 32, "No LOS since " + str(round(time.time() - start_time, 1)) + " seconds", GREEN) + status, oof_flg = pll.read_out_of_frequency_flg(j) + # if oof_flg == True: + # win.addstr(line + 1, 32,"OOF seen ", RED) + #else: + # win.addstr(line + 1, 32, "No OOF since " + str(round(time.time() - start_time, 1)) + " seconds", GREEN) + # win.addstr(" "+conf[j]) + # line = line + 2 + #else: + #win.addstr(" Not used") + # line = line + 1 + # Measure frequencies + # line = line + 1 + # for port in freq.keys(): + # status, frequency_read = fpga.read_pll_port_frequency(device, port) + #win.addstr(11 + line, 1, "Port = " + str(port) + " : " + str(frequency_read), WHITE) + # win.addstr(line, 1, "Output "+ str(port)+ " : ",curses.A_BOLD) + # win.addstr(str(frequency_read)+" Hz (" + freq[port] +")") + # line = line +1 + # internal state machine + #line = line + 1 + #status, val = pll.read_run_mode() + #win.addstr(line, 1, "PLL mode : ", curses.A_BOLD) + #if val == "Normal": + # win.addstr(val, GREEN) + #else: + # win.addstr(val, RED) + # check lock + line = line + 1 + status, val = pll.read_loss_of_lock() + win.addstr(line, 1, "PLL status: ", curses.A_BOLD) + if val == True: + win.addstr("Loss of lock", RED) + else: + win.addstr("Locked", GREEN) + # check sticky bit + status, val = pll.read_loss_of_lock_flg() + if val == True: + win.addstr(line, 32, "LOL seen", RED) + else: + win.addstr(line, 32, "No LOL since " + str(round(time.time() - start_time, 1)) + " seconds", GREEN) + win.refresh() + # Read masks values + # y_max, x_max = win.getmaxyx() + # line = 8 + # col = x_max / 3 + # win.addstr(line, col, "INTR flag values:",curses.A_BOLD) + # line = line + 1 + # masks = pll.read_mask_values() + # for mask in sorted(masks.keys()): + # win.addstr(line, col, mask + " : " + str(masks[mask])) + # line = line + 1 + # if line == y_max - 1: + # line = 8 + # col = col + x_max / 3 + win.refresh() + +def fanout_window(fpga, win): + status, frequency_read = fpga.read_pll_port_frequency("SI5340", 0) + win.addstr(2, 1, "Face plate clock : ",curses.A_BOLD) + if frequency_read < 127000000 or frequency_read > 128000000: + win.addstr(str(frequency_read/1000)+" kHz", RED) + win.addstr(" Warning : frequency out of range", YELLOW) + else: + win.addstr(str(frequency_read) + " Hz", GREEN) + win.refresh() + +def program_plls(plls, devices, files, win): + + #win.move(2,1) + win.clrtobot() + win.box() + line = 3 + + for i in plls.keys(): # programs the 3 PLLs + (status, part_number) = plls[i].read_part_number() + (status, revision) = plls[i].read_device_revision() + win.addstr(line, 1, "===== Hard resetting PLL "+str(devices[i])+" =====") + plls[i].hard_reset() + win.addstr(line , 1, "..... Done ...................................................") + win.addstr(line , 1, "===== Programming PLL "+str(devices[i])+"======================") + #win.addstr(line + 3, 1, "..... Configuration file is " + files[i]) + #win.addstr(line + 4, 1, "..... Part number detected is : " + hex(part_number)) + #win.addstr(line + 5, 1, "..... Device revision detected is : Rev. " + revision) + win.refresh() + plls[i].si534x_programming(files[i]) + win.addstr(line , 1, "..... Done ...................................................") + for input in range(0, 4): + plls[i].enable_los(input) + plls[i].enable_oof(input) + win.refresh() + line = line + win.addstr(line, 1, "..... wait to stabilize ..................................") + win.refresh() + time.sleep(7) + win.addstr(line, 1, "..... ready ..............................................") + line = 32 + for i in plls.keys(): + plls[i].clear_lol_flg_bit() + plls[i].clear_los_oof_flg_reg() + # dic = plls[i].clear_los_oof_flg_reg() + # for mes in dic: + # win.addstr(line, 1, mes + dic[mes]) + # line = line + 1 + start_time = time.time() + win.refresh() + +def draw_menu(stdscr, dev): + + os.chdir("../Python/components") + + # Creates xcvr object + trans = xcvr(dev) + + # Creates Arria10 object + fpga = Arria10(dev) + + # Creates pll objects + pll_si5345_1 = Si534x(dev, 1, 0x68) + pll_si5345_2 = Si534x(dev, 2, 0x68) + pll_si5344 = Si534x(dev, 3, 0x68) + plls = \ + {1: pll_si5345_1, + 2: pll_si5345_2, + 3: pll_si5344 + } + devices = \ + {1: "SI5345_U23", + 2: "SI5345_U48", + 3: "SI5344_U54" + } + ### Files for configuration for FTSW clock + files1b = \ + {1: "../data/Si5345-1-BII_FTSW-Registers.txt", + 2: "../data/Si5345-2-BII_FTSW-Registers.txt", + 3: "../data/Si5344-BII_FTSW-Registers.txt" + } + conf1 = \ + {1: ["Expected frequency = 127.216 MHz", "Not used", "Not used", "Not used"], + 2: ["Expected frequency = 127.216 MHz", "Not used", "Not used", "Not used"], + 3: ["Expected frequency = 127.216 MHz", "Not used", "Not used", "Not used"] + } + # Modif EJ EP 17-01-2019 changement 2 premiers fichiers programmation pll + ### Files for configuration for oscillator clock + files2b = \ + {1: "../data/Si5345-1-BII_FPGA-Registers.txt", + 2: "../data/Si5345-2-BII_FPGA-Registers.txt", + 3: "../data/Si5344-BII_OSCI-Registers.txt" + } + # Modif EJ EP 17-01-2019 changement 2 premiers fichiers programmation pll + conf2 = \ + {1: ["Not used", "Expected frequency = 127.216 MHz", "Not used", "Not used"], + 2: ["Not used", "Expected frequency = 127.216 MHz", "Not used", "Not used"], + 3: ["Expected frequency = 127.216 MHz", "Not used", "Not used", "Not used"] + } + freq = \ + {1: { + 0: "gbt_refclk0", + 1: "gbt_refclk1", + 2: "gbt_refclk2", + 3: "gbt_refclk3"}, + 2: { + 0: "gbt_refclk4", + 1: "gbt_refclk5", + 3: "gbt_refclk6", + 4: "gbt_refclk7", + 8: "sys_clk_240"}, + 3: { + 0: "tfc_refclk", + 1: "sys_clk_240"} + } + + # Choose default pll files + files = files1b + conf = conf1 + + + k = 0 + + global start_time + start_time = time.time() + + #curses.resizeterm(61, 200) + + # Clear and refresh the screen for a blank canvas + stdscr.clear() + stdscr.refresh() + + # Start colors in curses + curses.start_color() + curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK) + curses.init_pair(2, curses.COLOR_CYAN, curses.COLOR_BLACK) + curses.init_pair(3, curses.COLOR_RED, curses.COLOR_BLACK) + curses.init_pair(4, curses.COLOR_GREEN, curses.COLOR_BLACK) + curses.init_pair(5, curses.COLOR_YELLOW, curses.COLOR_BLACK) + global WHITE + global CYAN + global RED + global GREEN + global YELLOW + WHITE = curses.color_pair(1) + CYAN = curses.color_pair(2) + RED = curses.color_pair(3) + GREEN = curses.color_pair(4) + YELLOW = curses.color_pair(5) + + # define 4 windows proportional to max screen size + + y_max, x_max = stdscr.getmaxyx() + + win1 = stdscr.subwin(y_max/6, x_max-2, 0, 0) + win1.box() + win1.addstr(1, 1, "Command window", CYAN | curses.A_BOLD) + board = EepromAT24C(dev, const.EEPROM_FPGA_BUS, const.EEPROM_U64_ADD) + val = board.read_identification() + val = val.split(":")[4] + val = val.replace("\"","") + val = val.split(",")[0] + win1.addstr(" Running on : " + val, CYAN | curses.A_BOLD) + win1.refresh() + + win2 = stdscr.subwin(y_max/6, + x_max - 2, + y_max/6, + 0) + win2.box() + win2.addstr(1, 1, "PLL SI54345_1", CYAN | curses.A_BOLD) + win2.refresh() + + win3 = stdscr.subwin(y_max/6, + x_max - 2, + 2*y_max/6, + 0) + win3.box() + win3.addstr(1, 1, "PLL SI54345_2", CYAN | curses.A_BOLD) + win3.refresh() + + win4 = stdscr.subwin( y_max/6 , x_max-2 , 3*y_max/6, 0 ) + win4.box() + win4.addstr(1, 1, "PLL SI54344", CYAN | curses.A_BOLD) + win4.refresh() + + win5 = stdscr.subwin(y_max/6, + x_max -2, + 4*y_max/6, + 0) + win5.box() + win5.addstr(1, 1, "Clock FTSW", CYAN | curses.A_BOLD) + win5.refresh() + + win6 = stdscr.subwin(y_max/6, + x_max -2, + 5*y_max/6, + 0) + win6.box() + win6.addstr(1, 1, "F2: Program PLLs (source = FTSW), F3: Program PLLs (source = Osci.)", CYAN | curses.A_BOLD) + win6.addstr(2, 1, "F4: Clear LOS/OOF/LOL Flag, F5 : Hard reset, F6: Soft reset", CYAN | curses.A_BOLD) + win6.refresh() + + # Loop where k is the last character pressed + while (k != ord ('q')): + + # Initialization + + # height, width = stdscr.getmaxyx () + + if k == curses.KEY_DOWN: + cursor_y = cursor_y + 1 + elif k == curses.KEY_UP: + cursor_y = cursor_y - 1 + elif k == curses.KEY_RIGHT: + cursor_x = cursor_x + 1 + elif k == curses.KEY_LEFT: + cursor_x = cursor_x - 1 + elif k == curses.KEY_F2: + win1.move(2, 1) + win1.clrtobot() + win1.box() + win1.addstr(2, 1, "Programming PLLs (source = FTSW)" , curses.A_BOLD) + files = files1b + conf = conf1 + program_plls(plls, devices, files, win1) + win2.move(2, 1) + win2.clrtobot() + win2.box() + win3.move(2, 1) + win3.clrtobot() + win3.box() + win4.move(2, 1) + win4.clrtobot() + win4.box() + elif k == curses.KEY_F3: + win1.move(2, 1) + win1.clrtobot() + win1.box() + win1.addstr(2, 1, "Programming PLLs (source = Oscillator) " , curses.A_BOLD) + files = files2b + conf = conf2 + program_plls(plls, devices, files, win1) + win2.move(2, 1) + win2.clrtobot() + win2.box() + win3.move(2, 1) + win3.clrtobot() + win3.box() + win4.move(2, 1) + win4.clrtobot() + win4.box() + elif k == curses.KEY_F4: + win1.move(2, 1) + win1.clrtobot() + win1.box() + start_time = time.time() + win1.addstr(3, 1, " Clearing input LOS and output LOL sticky bit ", WHITE) + for i in plls.keys(): + plls[i].clear_lol_flg_bit() + plls[i].clear_los_oof_flg_reg() + win1.refresh() + elif k== curses.KEY_F5: + line = 3 + win1.move(2, 1) + win1.clrtobot() + win1.box() + for i in plls.keys(): + win1.addstr(line, 1, "Sending Hard reset to device "+devices[i]) + plls[i].hard_reset() + line = line + 1 + win1.addstr(line, 1, "..... Done") + line = line + 1 + win1.refresh() + elif k== curses.KEY_F6: + line = 3 + win1.move(2, 1) + win1.clrtobot() + win1.box() + for i in plls.keys(): + win1.addstr(line, 1, "Sending Soft reset to device "+devices[i]) + plls[i].soft_reset() + line = line + 1 + win1.addstr(line, 1, "..... Done") + line = line + 1 + win1.refresh() + elif k== curses.KEY_F7: + y_max, x_max = win1.getmaxyx() + win1.move(2, 1) + win1.clrtobot() + win1.box() + win1.addstr(2, 1, " Initializing INTR masks ", WHITE) + line = 3 + col = 1 + for i in plls.keys(): + plls[i].init_mask_values() + win1.addstr(line, 1, devices[i]) + masks = plls[i].read_mask_values() + for mask in sorted(masks.keys()): + win1.addstr(line, col, mask + " : " + str(masks[mask])) + line = line + 1 + col = col + x_max / 3 + line = 3 + + + + # cursor_x = max (0, cursor_x) + # cursor_x = min (width - 1, cursor_x) + # + # cursor_y = max (0, cursor_y) + # cursor_y = min (height - 1, cursor_y) + + # Refresh windows with pll information + pll_window(pll_si5345_1, devices[1], fpga, freq[1], conf[1], win2) + pll_window(pll_si5345_2, devices[2], fpga, freq[2], conf[2], win3) + pll_window(pll_si5344 , devices[3], fpga, freq[3], conf[3], win4) + fanout_window(fpga, win5) + + + # Refresh the screen + #stdscr.refresh () + + # Wait for next input + stdscr.nodelay (True) + k = stdscr.getch () + + +def main(): + if (len(sys.argv) != 2): + print "Missing argument" + print "Syntax : config_PLLs <Nb_of_card> where Nb_of_pcie_slot = 0 or 2" + exit() + elif (sys.argv[1] == "0"): + print + print "===== Target board = 0" + dev = 0 + elif (sys.argv[1] == "2"): + print + print "===== Target board = 2" + dev = 2 + else: + print "Wrong argument" + print "Syntax : config_PLLs <Nb_of_card> where Nb_of_pcie_slot = 0 or 2" + exit() + curses.wrapper (draw_menu, dev) + + +if __name__ == "__main__": + + size = subprocess.Popen("stty size", shell=True, stdout=subprocess.PIPE).stdout + result = size.read() + result = result.replace("\n","") + y = int(result.split(" ")[0]) + x = int(result.split(" ")[1]) + print "Your window's x =" , x + print "Your window's y =" , y + if x < 79 or y < 34: + print "Your terminal window is too small (should be at least x=80, y=35)" + quit() + + + main ()