coredevice/mirny: better error handling for clk_sel

Signed-off-by: Etienne Wodey <wodey@iqo.uni-hannover.de>
This commit is contained in:
Etienne Wodey 2021-02-02 16:23:47 +01:00
parent 78e1b9f8e5
commit d691b05d78
1 changed files with 27 additions and 15 deletions

View File

@ -43,36 +43,41 @@ class Mirny:
valid options are: "XO" - onboard crystal oscillator valid options are: "XO" - onboard crystal oscillator
"SMA" - front-panel SMA connector "SMA" - front-panel SMA connector
"MMCX" - internal MMCX connector "MMCX" - internal MMCX connector
Passing an integer writes its two least significant bits as ``clk_sel`` Passing an integer writes it as ``clk_sel`` in the CPLD's register 1.
in the CPLD's register 1. The effect depends on the hardware revision. The effect depends on the hardware revision.
:param core_device: Core device name (default: "core") :param core_device: Core device name (default: "core")
""" """
kernel_invariants = {"bus", "core", "refclk", "clk_sel_hw_rev"} kernel_invariants = {"bus", "core", "refclk", "clk_sel_hw_rev"}
def __init__(self, dmgr, spi_device, refclk=100e6, clk_sel=0, core_device="core"): def __init__(self, dmgr, spi_device, refclk=100e6, clk_sel="XO", core_device="core"):
self.core = dmgr.get(core_device) self.core = dmgr.get(core_device)
self.bus = dmgr.get(spi_device) self.bus = dmgr.get(spi_device)
# reference clock frequency # reference clock frequency
self.refclk = refclk self.refclk = refclk
assert 10 <= self.refclk / 1e6 <= 600, "Invalid refclk" if not (10 <= self.refclk / 1e6 <= 600):
raise ValueError("Invalid refclk")
# reference clock selection # reference clock selection
if isinstance(clk_sel, str): try:
self.clk_sel_hw_rev = { self.clk_sel_hw_rev = {
# clk source: [v1.1, v1.0] # clk source: [reserved, reserved, v1.1, v1.0]
"xo": [0, 0], "xo": [-1, -1, 0, 0],
"mmcx": [3, 2], "mmcx": [-1, -1, 3, 2],
"sma": [2, 3], "sma": [-1, -1, 2, 3],
}[clk_sel.lower()] }[clk_sel.lower()]
else: except AttributeError: # not a string, fallback to int
clk_sel = int(clk_sel) & 0x3 if clk_sel & 0x3 != clk_sel:
self.clk_sel_hw_rev = [clk_sel] * 2 raise ValueError("Invalid clk_sel") from None
self.clk_sel_hw_rev = [clk_sel] * 4
except KeyError:
raise ValueError("Invalid clk_sel") from None
self.clk_sel = -1 self.clk_sel = -1
# board hardware revision # board hardware revision
self.hw_rev = 0 # v1.0: 0b11, v1.1: 0b10 self.hw_rev = 0 # v1.0: 3, v1.1: 2
# TODO: support clk_div on v1.0 boards # TODO: support clk_div on v1.0 boards
@ -96,7 +101,10 @@ class Mirny:
""" """
Initialize and detect Mirny. Initialize and detect Mirny.
:param blind: Do not attempt to verify presence and compatibility. Select the clock source based the board's hardware revision.
Raise ValueError if the board's hardware revision is not supported.
:param blind: Verify presence and protocol compatibility. Raise ValueError on failure.
""" """
reg0 = self.read_reg(0) reg0 = self.read_reg(0)
self.hw_rev = reg0 & 0x3 self.hw_rev = reg0 & 0x3
@ -107,7 +115,11 @@ class Mirny:
delay(100 * us) # slack delay(100 * us) # slack
# select clock source # select clock source
self.clk_sel = self.clk_sel_hw_rev[self.hw_rev - 2] self.clk_sel = self.clk_sel_hw_rev[self.hw_rev]
if self.clk_sel < 0:
raise ValueError("Hardware revision not supported")
self.write_reg(1, (self.clk_sel << 4)) self.write_reg(1, (self.clk_sel << 4))
delay(1000 * us) delay(1000 * us)