Skip to content
Snippets Groups Projects
Commit 81605a13 authored by Patrick Robbe's avatar Patrick Robbe
Browse files

Add scripts to read PLLs registers

parent e9197526
No related branches found
No related tags found
No related merge requests found
# see the lhcb-pcie40lli system.h file for bus numbering
LTC2990_BUS = 0
LTC2990_U14_ADD = 0x4F # 1001 111x BACK connect side
LTC2990_U13_ADD = 0x4E # 1001 110x FRONT mezz side
LTC2990_U192_ADD = 0x4C # 1001 100x FPGA
SC18IS602_U86 = 0x2C
MAX1619_U16_BUS = 0
MAX1619_U16_ADD = 0x18
# PLL cleaner 1
SI5345_U23_BUS = 1
SI5345_U23_ADD = 0x68
SI5345_U23_PORTS = [0, 1, 2, 3]
# PLL cleaner 2
SI5345_U48_BUS = 2
SI5345_U48_ADD = 0x68
SI5345_U48_PORTS = [0, 1, 3, 4, 8]
# PLL TFC
SI5344_U54_BUS = 3
SI5344_U54_ADD = 0x68
SI5344_U54_PORTS = [0, 1]
# fanout PCIe
SI53154_U11_BUS = 4
SI53154_U11_ADD = 0x6B
# 10G SFP+ 1
AFBR709_U19_BUS = 5
AFBR709_U19_ADD = 0x50
# 10G SFP+ 2
AFBR709_U219_BUS = 6
AFBR709_U219_ADD = 0x50
# Minipods
MINIPOD_BUS = 7
MINIPOD_TX_1_U2 = 0x28
MINIPOD_TX_2_U4 = 0x29
MINIPOD_TX_3_U6 = 0x2A
MINIPOD_TX_4_U8 = 0x2B
MINIPOD_RX_1_U3 = 0x30
MINIPOD_RX_2_U5 = 0x31
MINIPOD_RX_3_U7 = 0x32
MINIPOD_RX_4_U9 = 0x33
# temperatures on mezzanine
LTC2990_PWR_BUS = 8
EEPROM_U19_ADD = 0x50
LTC2990_U22_ADD = 0x4C # ??(1001 111x) mezzanine
LTC2990_U37_ADD = 0x4D # ??(1001 110x) mezzanine
# EEPROM for board identification
EEPROM_FPGA_BUS = 9
EEPROM_U64_ADD = 0x50
# voltage and current measurements
# SPI components we use the QSYS BASE address and not BUS number
# I2C_BUS_CURRENT1 = 10
LTC2418_U100_ADD = 0x20000
LTC2418_U100_0_9V = 0
LTC2418_U100_1_02VCCR = 4
LTC2418_U100_1_02VCCT = 6
LTC2418_U100_1_8V = 2
LTC2418_U100_1_8VCCPT = 8
LTC2418_U100_1_8VA10 = 10
LTC2418_U100_2_5V = 14
LTC2418_U100_3_3V = 12
# I2C_BUS_CURRENT2 = 11
LTC2498_U87_ADD = 0x20020
LTC2498_U87_12V = 0
LTC2498_U87_12VATX = 2
#!/usr/bin/python
# -*- coding: utf8 -*-
"""
xcvr_status.py -- module to display pll status
Author
JPC : 02/10/2018
"""
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 = 3
for j in range(0, 4):
status, loss_of_signal = pll.read_loss_of_signal(j)
win.addstr(line, 1, "Input " + str(j) + " : ",curses.A_BOLD)
if conf[j] != "Not used":
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, "Oscillator or 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(4,1)
win.clrtobot()
win.box()
line = 4
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, 1, "..... Done")
win.addstr(line + 2, 1, "===== Programming PLL ")
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 + 6, 1, "..... Done")
for input in range(0, 4):
plls[i].enable_los(input)
plls[i].enable_oof(input)
win.refresh()
line = line + 9
win.addstr(30, 1, "..... wait to stabilize")
win.refresh()
time.sleep(7)
win.addstr(31, 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"
}
files1b = \
{1: "../data/Si5345-RevB-JIT1_40_jitter1_input0_40MHz-Registers.txt",
2: "../data/Si5345-RevB-JIT2_40_jitter2_input0_40MHz-Registers.txt",
3: "../data/Si5344-RevB-TFC_40-Registers.txt"
}
files1d = \
{1: "../data/Si5345-RevD-JIT1_40_jitter1_input0_40MHz-Registers.txt",
2: "../data/Si5345-RevD-JIT2_40_jitter2_input0_40MHz-Registers.txt",
3: "../data/Si5344-RevD-TFC_40-Registers.txt"
}
conf1 = \
{1: ["Expected frequency = 40.0789 MHz", "Not used", "Not used", "Not used"],
2: ["Expected frequency = 40.0789 MHz", "Not used", "Not used", "Not used"],
3: ["Expected frequency = 40.0789 MHz", "Not used", "Not used", "Not used"]
}
# Modif EJ EP 17-01-2019 changement 2 premiers fichiers programmation pll
#files2b = \
#{1: "../data/Si5345-RevB-JIT1_250_jitter1_input1_250MHz-Registers.txt",
#2: "../data/Si5345-RevB-JIT2_250_jitter2_input1_250MHz-Registers.txt",
#3: "../data/Si5344-RevB-TFC_127-Registers.txt"
#}
files2b = \
{1: "../data/Si5345-RevB-JIT1_255-JIT1_240_jitter1_input1_255MHz_new-Registers.txt",
2: "../data/Si5345-RevB-JIT2_255-JIT2_240_jitter2_input1_255MHz_new-Registers.txt",
3: "../data/Si5344-RevB-TFC_127-Registers.txt"
}
files2d = \
{1: "../data/Si5345-RevD-JIT1_240_jitter1_input1_240MHz-Registers.txt",
2: "../data/Si5345-RevD-JIT2_240_jitter2_input1_240MHz-Registers.txt",
3: "../data/Si5344-RevD-TFC_40-Registers.txt"
}
# Modif EJ EP 17-01-2019 changement 2 premiers fichiers programmation pll
#conf2 = \
#{1: ["Not used", "Expected frequency = 250 MHz", "Not used", "Not used"],
#2: ["Not used", "Expected frequency = 250 MHz", "Not used", "Not used"],
#3: ["Expected frequency = 127 MHz", "Not used", "Not used", "Not used"]
#}
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 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-9, 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/3 +1,
x_max/2,
0,
x_max/2)
win2.box()
win2.addstr(1, 1, "PLL SI54345_1", CYAN | curses.A_BOLD)
win2.refresh()
win3 = stdscr.subwin(y_max/3 +1,
x_max/2,
y_max/3 +1,
x_max/2)
win3.box()
win3.addstr(1, 1, "PLL SI54345_2", CYAN | curses.A_BOLD)
win3.refresh()
win4 = stdscr.subwin(min(y_max/3,y_max - (2*y_max/3 +1)),
x_max/2,
2*y_max/3 +1,
x_max/2)
win4.box()
win4.addstr(1, 1, "PLL SI54344", CYAN | curses.A_BOLD)
win4.refresh()
win5 = stdscr.subwin(5,
x_max / 2,
y_max - 9,
0)
win5.box()
win5.addstr(1, 1, "Clock Fanout", CYAN | curses.A_BOLD)
win5.refresh()
win6 = stdscr.subwin(4,
x_max / 2,
y_max - 4,
0)
win6.box()
win6.addstr(1, 1, "F2: Program PLLs (source = fanout), F3: Program PLLs (source = FPGA))", 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(3, 1, "Programming PLLs (source = fanout)")
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(3, 1, "Programming PLLs (source = FPGA) ")
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 "x =" , x
print "y =" , y
if x < 180 or y < 53:
print "Decrease police size by typing \"ctrl -\" and rerun"
quit()
main ()
"""
readPLLRegister.py -- module to read external PLLs registers via i2c
Author
PR: First version
"""
import time
import os
import pathtocomponents
import sys
from fpga_comp import Arria10
from si534x_comp import Si534x
from xcvr_comp import xcvr
def main():
if (len(sys.argv) != 2):
print "Missing argument"
print "Syntax : config_PLLs <Nb_of_card> where Nb_of_pcie_slot"
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()
# Program PLLs
devices = \
{1: "SI5345_U23",
2: "SI5345_U48",
3: "SI5344_U54"
}
ports = \
{1: [0, 1, 2, 3],
2: [0, 1, 3, 4, 8],
3: [0, 1]
}
#dev = 0 # Creates a list of objects with the 3 PLLs
add = 0x68
pll = [Si534x(dev, bus, add) for bus in devices.keys()]
print
for i in devices.keys(): # programs the 3 PLLs
print "-----------------------------------------------"
status, val = pll[i-1].read_part_number()
print "..... Type of chip =", format(val,'x')
status, val = pll[i-1].read_device_revision()
print "..... Revision =", val
print "-----------------------------------------------"
# Measure clocks
if __name__ == "__main__":
main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment