coredevice/mirny: port to NAC3

This commit is contained in:
Sebastien Bourdeauducq 2021-11-23 17:13:43 +08:00
parent f5a5b7a22a
commit 29f42ccd8a

View File

@ -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)