From d691b05d78af880ebb7432f52f5d21ec0357a6ae Mon Sep 17 00:00:00 2001 From: Etienne Wodey Date: Tue, 2 Feb 2021 16:23:47 +0100 Subject: [PATCH] coredevice/mirny: better error handling for clk_sel Signed-off-by: Etienne Wodey --- artiq/coredevice/mirny.py | 42 +++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/artiq/coredevice/mirny.py b/artiq/coredevice/mirny.py index 29d6d6481..a29f57aeb 100644 --- a/artiq/coredevice/mirny.py +++ b/artiq/coredevice/mirny.py @@ -43,36 +43,41 @@ class Mirny: valid options are: "XO" - onboard crystal oscillator "SMA" - front-panel SMA connector "MMCX" - internal MMCX connector - Passing an integer writes its two least significant bits as ``clk_sel`` - in the CPLD's register 1. The effect depends on the hardware revision. + Passing an integer writes it as ``clk_sel`` in the CPLD's register 1. + The effect depends on the hardware revision. :param core_device: Core device name (default: "core") """ 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.bus = dmgr.get(spi_device) # reference clock frequency 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 - if isinstance(clk_sel, str): + try: self.clk_sel_hw_rev = { - # clk source: [v1.1, v1.0] - "xo": [0, 0], - "mmcx": [3, 2], - "sma": [2, 3], + # clk source: [reserved, reserved, v1.1, v1.0] + "xo": [-1, -1, 0, 0], + "mmcx": [-1, -1, 3, 2], + "sma": [-1, -1, 2, 3], }[clk_sel.lower()] - else: - clk_sel = int(clk_sel) & 0x3 - self.clk_sel_hw_rev = [clk_sel] * 2 + except AttributeError: # not a string, fallback to int + if clk_sel & 0x3 != clk_sel: + 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 # 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 @@ -96,7 +101,10 @@ class 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) self.hw_rev = reg0 & 0x3 @@ -107,7 +115,11 @@ class Mirny: delay(100 * us) # slack # 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)) delay(1000 * us)