mirror of https://github.com/m-labs/artiq.git
coredevice/mirny: port to NAC3
This commit is contained in:
parent
f5a5b7a22a
commit
29f42ccd8a
|
@ -1,23 +1,24 @@
|
||||||
"""RTIO driver for Mirny (4 channel GHz PLLs)
|
"""RTIO driver for Mirny (4 channel GHz PLLs)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from artiq.language.core import kernel, delay
|
from artiq.language.core import nac3, KernelInvariant, kernel
|
||||||
from artiq.language.units import us
|
from artiq.language.units import us
|
||||||
|
|
||||||
from numpy import int32
|
from numpy import int32
|
||||||
|
|
||||||
from artiq.coredevice import spi2 as spi
|
from artiq.coredevice.core import Core
|
||||||
|
from artiq.coredevice.spi2 import *
|
||||||
|
|
||||||
|
|
||||||
SPI_CONFIG = (
|
SPI_CONFIG = (
|
||||||
0 * spi.SPI_OFFLINE
|
0 * SPI_OFFLINE
|
||||||
| 0 * spi.SPI_END
|
| 0 * SPI_END
|
||||||
| 0 * spi.SPI_INPUT
|
| 0 * SPI_INPUT
|
||||||
| 1 * spi.SPI_CS_POLARITY
|
| 1 * SPI_CS_POLARITY
|
||||||
| 0 * spi.SPI_CLK_POLARITY
|
| 0 * SPI_CLK_POLARITY
|
||||||
| 0 * spi.SPI_CLK_PHASE
|
| 0 * SPI_CLK_PHASE
|
||||||
| 0 * spi.SPI_LSB_FIRST
|
| 0 * SPI_LSB_FIRST
|
||||||
| 0 * spi.SPI_HALF_DUPLEX
|
| 0 * SPI_HALF_DUPLEX
|
||||||
)
|
)
|
||||||
|
|
||||||
# SPI clock write and read dividers
|
# SPI clock write and read dividers
|
||||||
|
@ -32,6 +33,7 @@ WE = 1 << 24
|
||||||
PROTO_REV_MATCH = 0x0
|
PROTO_REV_MATCH = 0x0
|
||||||
|
|
||||||
|
|
||||||
|
@nac3
|
||||||
class Mirny:
|
class Mirny:
|
||||||
"""
|
"""
|
||||||
Mirny PLL-based RF generator.
|
Mirny PLL-based RF generator.
|
||||||
|
@ -46,8 +48,12 @@ class Mirny:
|
||||||
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")
|
||||||
"""
|
"""
|
||||||
|
core: KernelInvariant[Core]
|
||||||
kernel_invariants = {"bus", "core", "refclk", "clk_sel_hw_rev"}
|
bus: KernelInvariant[SPIMaster]
|
||||||
|
refclk: KernelInvariant[float]
|
||||||
|
clk_sel_hw_rev: list[int32]
|
||||||
|
hw_rev: int32
|
||||||
|
clk_sel: int32
|
||||||
|
|
||||||
def __init__(self, dmgr, spi_device, refclk=100e6, clk_sel="XO", 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)
|
||||||
|
@ -81,22 +87,22 @@ class Mirny:
|
||||||
# TODO: support clk_div on v1.0 boards
|
# TODO: support clk_div on v1.0 boards
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def read_reg(self, addr):
|
def read_reg(self, addr: int32) -> int32:
|
||||||
"""Read a register"""
|
"""Read a register"""
|
||||||
self.bus.set_config_mu(
|
self.bus.set_config_mu(
|
||||||
SPI_CONFIG | spi.SPI_INPUT | spi.SPI_END, 24, SPIT_RD, SPI_CS
|
SPI_CONFIG | SPI_INPUT | SPI_END, 24, SPIT_RD, SPI_CS
|
||||||
)
|
)
|
||||||
self.bus.write((addr << 25))
|
self.bus.write((addr << 25))
|
||||||
return self.bus.read() & int32(0xFFFF)
|
return self.bus.read() & 0xFFFF
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def write_reg(self, addr, data):
|
def write_reg(self, addr: int32, data: int32):
|
||||||
"""Write a register"""
|
"""Write a register"""
|
||||||
self.bus.set_config_mu(SPI_CONFIG | spi.SPI_END, 24, SPIT_WR, SPI_CS)
|
self.bus.set_config_mu(SPI_CONFIG | SPI_END, 24, SPIT_WR, SPI_CS)
|
||||||
self.bus.write((addr << 25) | WE | ((data & 0xFFFF) << 8))
|
self.bus.write((addr << 25) | WE | ((data & 0xFFFF) << 8))
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def init(self, blind=False):
|
def init(self, blind: bool = False):
|
||||||
"""
|
"""
|
||||||
Initialize and detect Mirny.
|
Initialize and detect Mirny.
|
||||||
|
|
||||||
|
@ -110,33 +116,35 @@ class Mirny:
|
||||||
|
|
||||||
if not blind:
|
if not blind:
|
||||||
if (reg0 >> 2) & 0x3 != PROTO_REV_MATCH:
|
if (reg0 >> 2) & 0x3 != PROTO_REV_MATCH:
|
||||||
raise ValueError("Mirny PROTO_REV mismatch")
|
# NAC3TODO raise ValueError("Mirny PROTO_REV mismatch")
|
||||||
delay(100 * us) # slack
|
pass
|
||||||
|
self.core.delay(100. * us) # slack
|
||||||
|
|
||||||
# select clock source
|
# select clock source
|
||||||
self.clk_sel = self.clk_sel_hw_rev[self.hw_rev]
|
self.clk_sel = self.clk_sel_hw_rev[self.hw_rev]
|
||||||
|
|
||||||
if self.clk_sel < 0:
|
if self.clk_sel < 0:
|
||||||
raise ValueError("Hardware revision not supported")
|
# NAC3TODO raise ValueError("Hardware revision not supported")
|
||||||
|
pass
|
||||||
|
|
||||||
self.write_reg(1, (self.clk_sel << 4))
|
self.write_reg(1, (self.clk_sel << 4))
|
||||||
delay(1000 * us)
|
self.core.delay(1000. * us)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def set_att_mu(self, channel, att):
|
def set_att_mu(self, channel: int32, att: int32):
|
||||||
"""Set digital step attenuator in machine units.
|
"""Set digital step attenuator in machine units.
|
||||||
|
|
||||||
:param att: Attenuation setting, 8 bit digital.
|
:param att: Attenuation setting, 8 bit digital.
|
||||||
"""
|
"""
|
||||||
self.bus.set_config_mu(SPI_CONFIG | spi.SPI_END, 16, SPIT_WR, SPI_CS)
|
self.bus.set_config_mu(SPI_CONFIG | SPI_END, 16, SPIT_WR, SPI_CS)
|
||||||
self.bus.write(((channel | 8) << 25) | (att << 16))
|
self.bus.write(((channel | 8) << 25) | (att << 16))
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def write_ext(self, addr, length, data):
|
def write_ext(self, addr: int32, length: int32, data: int32):
|
||||||
"""Perform SPI write to a prefixed address"""
|
"""Perform SPI write to a prefixed address"""
|
||||||
self.bus.set_config_mu(SPI_CONFIG, 8, SPIT_WR, SPI_CS)
|
self.bus.set_config_mu(SPI_CONFIG, 8, SPIT_WR, SPI_CS)
|
||||||
self.bus.write(addr << 25)
|
self.bus.write(addr << 25)
|
||||||
self.bus.set_config_mu(SPI_CONFIG | spi.SPI_END, length, SPIT_WR, SPI_CS)
|
self.bus.set_config_mu(SPI_CONFIG | SPI_END, length, SPIT_WR, SPI_CS)
|
||||||
if length < 32:
|
if length < 32:
|
||||||
data <<= 32 - length
|
data <<= 32 - length
|
||||||
self.bus.write(data)
|
self.bus.write(data)
|
||||||
|
|
Loading…
Reference in New Issue