forked from M-Labs/artiq
Merge pull request #1601 from airwoodix/enh-mirny-clksel
mirny: hw_rev independent, human readable clk_sel
This commit is contained in:
commit
0c634c7a46
|
@ -32,6 +32,8 @@ Highlights:
|
||||||
* Zotino now exposes ``voltage_to_mu()``
|
* Zotino now exposes ``voltage_to_mu()``
|
||||||
* ``ad9910``: The maximum amplitude scale factor is now ``0x3fff`` (was ``0x3ffe``
|
* ``ad9910``: The maximum amplitude scale factor is now ``0x3fff`` (was ``0x3ffe``
|
||||||
before).
|
before).
|
||||||
|
* Mirny now supports HW revision independent, human readable ``clk_sel`` parameters:
|
||||||
|
"XO", "SMA", and "MMCX". Passing an integer is backwards compatible.
|
||||||
* Dashboard:
|
* Dashboard:
|
||||||
- Applets now restart if they are running and a ccb call changes their spec
|
- Applets now restart if they are running and a ccb call changes their spec
|
||||||
- A "Quick Open" dialog to open experiments by typing part of their name can
|
- A "Quick Open" dialog to open experiments by typing part of their name can
|
||||||
|
|
|
@ -28,6 +28,9 @@ SPI_CS = 1
|
||||||
|
|
||||||
WE = 1 << 24
|
WE = 1 << 24
|
||||||
|
|
||||||
|
# supported CPLD code version
|
||||||
|
PROTO_REV_MATCH = 0x0
|
||||||
|
|
||||||
|
|
||||||
class Mirny:
|
class Mirny:
|
||||||
"""
|
"""
|
||||||
|
@ -37,22 +40,44 @@ class Mirny:
|
||||||
:param refclk: Reference clock (SMA, MMCX or on-board 100 MHz oscillator)
|
:param refclk: Reference clock (SMA, MMCX or on-board 100 MHz oscillator)
|
||||||
frequency in Hz
|
frequency in Hz
|
||||||
:param clk_sel: Reference clock selection.
|
:param clk_sel: Reference clock selection.
|
||||||
valid options are: 0 - internal 100MHz XO; 1 - front-panel SMA; 2 -
|
valid options are: "XO" - onboard crystal oscillator
|
||||||
internal MMCX
|
"SMA" - front-panel SMA connector
|
||||||
|
"MMCX" - internal MMCX connector
|
||||||
|
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")
|
:param core_device: Core device name (default: "core")
|
||||||
"""
|
"""
|
||||||
|
|
||||||
kernel_invariants = {"bus", "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.core = dmgr.get(core_device)
|
||||||
self.bus = dmgr.get(spi_device)
|
self.bus = dmgr.get(spi_device)
|
||||||
|
|
||||||
|
# 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")
|
||||||
|
|
||||||
self.clk_sel = clk_sel & 0b11
|
# reference clock selection
|
||||||
assert 0 <= self.clk_sel <= 3, "Invalid clk_sel"
|
try:
|
||||||
|
self.clk_sel_hw_rev = {
|
||||||
|
# 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()]
|
||||||
|
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: 3, v1.1: 2
|
||||||
|
|
||||||
# TODO: support clk_div on v1.0 boards
|
# TODO: support clk_div on v1.0 boards
|
||||||
|
|
||||||
|
@ -76,17 +101,25 @@ 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.
|
||||||
"""
|
"""
|
||||||
if not blind:
|
|
||||||
reg0 = self.read_reg(0)
|
reg0 = self.read_reg(0)
|
||||||
if reg0 & 0b11 != 0b11:
|
self.hw_rev = reg0 & 0x3
|
||||||
raise ValueError("Mirny HW_REV mismatch")
|
|
||||||
if (reg0 >> 2) & 0b11 != 0b00:
|
if not blind:
|
||||||
|
if (reg0 >> 2) & 0x3 != PROTO_REV_MATCH:
|
||||||
raise ValueError("Mirny PROTO_REV mismatch")
|
raise ValueError("Mirny PROTO_REV mismatch")
|
||||||
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]
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
|
@ -291,18 +291,7 @@ class SinaraTester(EnvExperiment):
|
||||||
@kernel
|
@kernel
|
||||||
def init_mirny(self, cpld):
|
def init_mirny(self, cpld):
|
||||||
self.core.break_realtime()
|
self.core.break_realtime()
|
||||||
# Taken from Mirny.init(), to accomodate Mirny v1.1 without blinding
|
cpld.init()
|
||||||
reg0 = cpld.read_reg(0)
|
|
||||||
if reg0 & 0b11 != 0b10: # Modified part
|
|
||||||
raise ValueError("Mirny HW_REV mismatch")
|
|
||||||
if (reg0 >> 2) & 0b11 != 0b00:
|
|
||||||
raise ValueError("Mirny PROTO_REV mismatch")
|
|
||||||
delay(100 * us) # slack
|
|
||||||
|
|
||||||
# select clock source
|
|
||||||
cpld.write_reg(1, (cpld.clk_sel << 4))
|
|
||||||
delay(1000 * us)
|
|
||||||
# End of modified Mirny.init()
|
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def setup_mirny(self, channel, frequency):
|
def setup_mirny(self, channel, frequency):
|
||||||
|
|
Loading…
Reference in New Issue