forked from M-Labs/artiq
coredevice: mirny/adf5355: add basic high-level interface
Signed-off-by: Etienne Wodey <wodey@iqo.uni-hannover.de>
This commit is contained in:
parent
4f311e7448
commit
211500089f
|
@ -9,14 +9,39 @@ on Mirny-style prefixed SPI buses.
|
|||
# https://www.analog.com/media/en/technical-documentation/user-guides/EV-ADF5356SD1Z-UG-1087.pdf
|
||||
|
||||
|
||||
from artiq.language.core import kernel, delay
|
||||
from artiq.language.units import us
|
||||
from artiq.language.core import kernel, portable, rpc, delay
|
||||
from artiq.language.units import us, GHz, MHz
|
||||
from artiq.language.types import TInt32, TInt64
|
||||
from artiq.coredevice import spi2 as spi
|
||||
from artiq.coredevice.adf5355_reg import *
|
||||
|
||||
SPI_CONFIG = (0*spi.SPI_OFFLINE | 0*spi.SPI_END |
|
||||
0*spi.SPI_INPUT | 1*spi.SPI_CS_POLARITY |
|
||||
0*spi.SPI_CLK_POLARITY | 0*spi.SPI_CLK_PHASE |
|
||||
0*spi.SPI_LSB_FIRST | 0*spi.SPI_HALF_DUPLEX)
|
||||
from fractions import Fraction
|
||||
from numpy import int32, int64, floor, ceil
|
||||
|
||||
|
||||
SPI_CONFIG = (
|
||||
0 * spi.SPI_OFFLINE
|
||||
| 0 * spi.SPI_END
|
||||
| 0 * spi.SPI_INPUT
|
||||
| 1 * spi.SPI_CS_POLARITY
|
||||
| 0 * spi.SPI_CLK_POLARITY
|
||||
| 0 * spi.SPI_CLK_PHASE
|
||||
| 0 * spi.SPI_LSB_FIRST
|
||||
| 0 * spi.SPI_HALF_DUPLEX
|
||||
)
|
||||
|
||||
|
||||
ADF5355_MIN_VCO_FREQ = int64(3.4 * GHz)
|
||||
ADF5355_MAX_VCO_FREQ = int64(6.8 * GHz)
|
||||
ADF5355_MAX_OUTA_FREQ = ADF5355_MAX_VCO_FREQ
|
||||
ADF5355_MIN_OUTA_FREQ = ADF5355_MIN_VCO_FREQ / 64
|
||||
ADF5355_MAX_OUTB_FREQ = ADF5355_MAX_VCO_FREQ * 2
|
||||
ADF5355_MIN_OUTB_FREQ = ADF5355_MIN_VCO_FREQ * 2
|
||||
|
||||
ADF5355_MAX_FREQ_PFD = int32(125.0 * MHz)
|
||||
ADF5355_MODULUS1 = int32(16777216)
|
||||
ADF5355_MAX_MODULUS2 = int32(16383) # FIXME: ADF5356 has 28 bits MOD2
|
||||
ADF5355_MAX_R_CNT = int32(1023)
|
||||
|
||||
|
||||
class ADF5355:
|
||||
|
@ -25,17 +50,57 @@ class ADF5355:
|
|||
:param cpld_device: Mirny CPLD device name
|
||||
:param sw_device: Mirny RF switch device name
|
||||
:param channel: Mirny RF channel index
|
||||
:param ref_doubler: enable/disable reference clock doubler
|
||||
:param ref_divider: enable/disable reference clock divide-by-2
|
||||
:param core_device: Core device name (default: "core")
|
||||
"""
|
||||
kernel_invariants = {"cpld", "sw", "channel", "core"}
|
||||
|
||||
def __init__(self, dmgr, cpld_device, sw_device, channel,
|
||||
core="core"):
|
||||
kernel_invariants = {"cpld", "sw", "channel", "core", "sysclk"}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
dmgr,
|
||||
cpld_device,
|
||||
sw_device,
|
||||
channel,
|
||||
ref_doubler=False,
|
||||
ref_divider=False,
|
||||
core="core",
|
||||
):
|
||||
self.cpld = dmgr.get(cpld_device)
|
||||
self.sw = dmgr.get(sw_device)
|
||||
self.channel = channel
|
||||
self.core = dmgr.get(core)
|
||||
|
||||
self.ref_doubler = ref_doubler
|
||||
self.ref_divider = ref_divider
|
||||
self.sysclk = self.cpld.refclk
|
||||
assert 10 <= self.sysclk / 1e6 <= 600
|
||||
|
||||
self._init_registers()
|
||||
|
||||
@kernel
|
||||
def init(self, blind=False):
|
||||
"""
|
||||
Initialize and configure the PLL.
|
||||
|
||||
:param blind: Do not attempt to verify presence.
|
||||
"""
|
||||
if not blind:
|
||||
# MUXOUT = VDD
|
||||
self.write(ADF5355_REG4_MUXOUT(1) | 4)
|
||||
delay(5000 * us)
|
||||
if not self.read_muxout():
|
||||
raise ValueError("MUXOUT not high")
|
||||
delay(1000 * us)
|
||||
|
||||
# MUXOUT = DGND
|
||||
self.write(ADF5355_REG4_MUXOUT(2) | 4)
|
||||
delay(5000 * us)
|
||||
if self.read_muxout():
|
||||
raise ValueError("MUXOUT not low")
|
||||
delay(1000 * us)
|
||||
|
||||
@kernel
|
||||
def set_att_mu(self, att):
|
||||
"""Set digital step attenuator in machine units.
|
||||
|
@ -53,13 +118,393 @@ class ADF5355:
|
|||
return bool(self.cpld.read_reg(0) & (1 << (self.channel + 8)))
|
||||
|
||||
@kernel
|
||||
def init(self):
|
||||
self.write((1 << 27) | 4)
|
||||
if not self.read_muxout():
|
||||
raise ValueError("MUXOUT not high")
|
||||
delay(100*us)
|
||||
self.write((2 << 27) | 4)
|
||||
if self.read_muxout():
|
||||
raise ValueError("MUXOUT not low")
|
||||
delay(100*us)
|
||||
self.write((6 << 27) | 4)
|
||||
def set_frequency(self, f):
|
||||
"""
|
||||
Output given frequency on output A.
|
||||
|
||||
:param f: 53.125 MHz <= f <= 6800 MHz
|
||||
"""
|
||||
freq = int64(round(f))
|
||||
|
||||
if freq > ADF5355_MAX_VCO_FREQ:
|
||||
raise ValueError("Requested too high frequency")
|
||||
|
||||
# select minimal output divider
|
||||
rf_div_sel = 0
|
||||
while freq < ADF5355_MIN_VCO_FREQ:
|
||||
freq <<= 1
|
||||
rf_div_sel += 1
|
||||
|
||||
if (1 << rf_div_sel) > 64:
|
||||
raise ValueError("Requested too low frequency")
|
||||
|
||||
# choose reference divider that maximizes PFD frequency
|
||||
self.regs[4] = ADF5355_REG4_R_COUNTER_UPDATE(
|
||||
self.regs[4], self._compute_reference_counter()
|
||||
)
|
||||
f_pfd = self.f_pfd()
|
||||
|
||||
# choose prescaler
|
||||
if freq > int64(6e9):
|
||||
self.regs[0] |= ADF5355_REG0_PRESCALER(1) # 8/9
|
||||
n_min, n_max = 75, 65535
|
||||
|
||||
# adjust reference divider to be able to match n_min constraint
|
||||
while n_min * f_pfd > freq:
|
||||
r = ADF5355_REG4_R_COUNTER_GET(self.regs[4])
|
||||
self.regs[4] = ADF5355_REG4_R_COUNTER_UPDATE(self.regs[4], r + 1)
|
||||
f_pfd = self.f_pfd()
|
||||
else:
|
||||
self.regs[0] &= ~ADF5355_REG0_PRESCALER(1) # 4/5
|
||||
n_min, n_max = 23, 32767
|
||||
|
||||
# calculate PLL parameters
|
||||
n, frac1, (frac2_msb, frac2_lsb), (mod2_msb, mod2_lsb) = calculate_pll(
|
||||
freq, f_pfd
|
||||
)
|
||||
|
||||
if not (n_min <= n <= n_max):
|
||||
raise ValueError("Invalid INT value")
|
||||
|
||||
# configure PLL
|
||||
self.regs[0] = ADF5355_REG0_INT_VALUE_UPDATE(self.regs[0], n)
|
||||
self.regs[1] = ADF5355_REG1_MAIN_FRAC_VALUE_UPDATE(self.regs[1], frac1)
|
||||
self.regs[2] = ADF5355_REG2_AUX_FRAC_LSB_VALUE_UPDATE(self.regs[2], frac2_lsb)
|
||||
self.regs[2] = ADF5355_REG2_AUX_MOD_LSB_VALUE_UPDATE(self.regs[2], mod2_lsb)
|
||||
self.regs[13] = ADF5355_REG13_AUX_FRAC_MSB_VALUE_UPDATE(
|
||||
self.regs[13], frac2_msb
|
||||
)
|
||||
self.regs[13] = ADF5355_REG13_AUX_MOD_MSB_VALUE_UPDATE(self.regs[13], mod2_msb)
|
||||
|
||||
self.regs[6] = ADF5355_REG6_RF_DIVIDER_SELECT_UPDATE(self.regs[6], rf_div_sel)
|
||||
self.regs[6] = ADF5355_REG6_CP_BLEED_CURRENT_UPDATE(
|
||||
self.regs[6], int32(floor(24 * f_pfd / (61.44 * MHz)))
|
||||
)
|
||||
self.regs[9] = ADF5355_REG9_VCO_BAND_DIVISION_UPDATE(
|
||||
self.regs[9], int32(ceil(f_pfd / 160e3))
|
||||
)
|
||||
|
||||
# commit
|
||||
# TODO: frequency update sync
|
||||
self.sync()
|
||||
|
||||
@kernel
|
||||
def sync(self):
|
||||
"""
|
||||
Write all registers to the device. Attempts to lock the PLL.
|
||||
"""
|
||||
f_pfd = self.f_pfd()
|
||||
|
||||
if f_pfd <= 75.0 * MHz:
|
||||
for i in range(13, 0, -1):
|
||||
self.write(self.regs[i])
|
||||
delay(200 * us)
|
||||
self.write(self.regs[0] | ADF5355_REG0_AUTOCAL(1))
|
||||
else:
|
||||
# AUTOCAL AT HALF PFD FREQUENCY
|
||||
|
||||
# calculate PLL at f_pfd/2
|
||||
n, frac1, (frac2_msb, frac2_lsb), (mod2_msb, mod2_lsb) = calculate_pll(
|
||||
self.f_vco(), f_pfd >> 1
|
||||
)
|
||||
|
||||
self.write(
|
||||
13
|
||||
| ADF5355_REG13_AUX_FRAC_MSB_VALUE(frac2_msb)
|
||||
| ADF5355_REG13_AUX_MOD_MSB_VALUE(mod2_msb)
|
||||
)
|
||||
|
||||
for i in range(12, 4, -1):
|
||||
self.write(self.regs[i])
|
||||
|
||||
self.write(
|
||||
ADF5355_REG4_R_COUNTER_UPDATE(self.regs[4], 2 * self.ref_counter())
|
||||
)
|
||||
|
||||
self.write(self.regs[3])
|
||||
self.write(
|
||||
2
|
||||
| ADF5355_REG2_AUX_MOD_LSB_VALUE(mod2_lsb)
|
||||
| ADF5355_REG2_AUX_FRAC_LSB_VALUE(frac2_lsb)
|
||||
)
|
||||
self.write(1 | ADF5355_REG1_MAIN_FRAC_VALUE(frac1))
|
||||
|
||||
delay(200 * us)
|
||||
self.write(ADF5355_REG0_INT_VALUE(n) | ADF5355_REG0_AUTOCAL(1))
|
||||
|
||||
# RELOCK AT WANTED PFD FREQUENCY
|
||||
|
||||
for i in [4, 2, 1]:
|
||||
self.write(self.regs[i])
|
||||
|
||||
# force-disable autocal
|
||||
self.write(self.regs[0] & ~ADF5355_REG0_AUTOCAL(1))
|
||||
|
||||
@portable
|
||||
def f_pfd(self) -> TInt64:
|
||||
"""
|
||||
Return the PFD frequency for the cached set of registers.
|
||||
"""
|
||||
r = ADF5355_REG4_R_COUNTER_GET(self.regs[4])
|
||||
d = ADF5355_REG4_R_DOUBLER_GET(self.regs[4])
|
||||
t = ADF5355_REG4_R_DIVIDER_GET(self.regs[4])
|
||||
return self._compute_pfd_frequency(r, d, t)
|
||||
|
||||
@portable
|
||||
def f_vco(self) -> TInt64:
|
||||
"""
|
||||
Return the VCO frequency for the cached set of registers.
|
||||
"""
|
||||
return int64(
|
||||
self.f_pfd()
|
||||
* (
|
||||
self.pll_n()
|
||||
+ (self.pll_frac1() + self.pll_frac2() / self.pll_mod2())
|
||||
/ ADF5355_MODULUS1
|
||||
)
|
||||
)
|
||||
|
||||
@portable
|
||||
def pll_n(self) -> TInt32:
|
||||
"""
|
||||
Return the PLL integer value (INT) for the cached set of registers.
|
||||
"""
|
||||
return ADF5355_REG0_INT_VALUE_GET(self.regs[0])
|
||||
|
||||
@portable
|
||||
def pll_frac1(self) -> TInt32:
|
||||
"""
|
||||
Return the main fractional value (FRAC1) for the cached set of registers.
|
||||
"""
|
||||
return ADF5355_REG1_MAIN_FRAC_VALUE_GET(self.regs[1])
|
||||
|
||||
@portable
|
||||
def pll_frac2(self) -> TInt32:
|
||||
"""
|
||||
Return the auxiliary fractional value (FRAC2) for the cached set of registers.
|
||||
"""
|
||||
return (
|
||||
ADF5355_REG13_AUX_FRAC_MSB_VALUE_GET(self.regs[13]) << 14
|
||||
) | ADF5355_REG2_AUX_FRAC_LSB_VALUE_GET(self.regs[2])
|
||||
|
||||
@portable
|
||||
def pll_mod2(self) -> TInt32:
|
||||
"""
|
||||
Return the auxiliary modulus value (MOD2) for the cached set of registers.
|
||||
"""
|
||||
return (
|
||||
ADF5355_REG13_AUX_MOD_MSB_VALUE_GET(self.regs[13]) << 14
|
||||
) | ADF5355_REG2_AUX_MOD_LSB_VALUE_GET(self.regs[2])
|
||||
|
||||
@portable
|
||||
def ref_counter(self) -> TInt32:
|
||||
"""
|
||||
Return the reference counter value (R) for the cached set of registers.
|
||||
"""
|
||||
return ADF5355_REG4_R_COUNTER_GET(self.regs[4])
|
||||
|
||||
@rpc
|
||||
def info(self):
|
||||
output_divider = 1 << ADF5355_REG6_RF_DIVIDER_SELECT_GET(self.regs[6])
|
||||
prescaler = ADF5355_REG0_PRESCALER_GET(self.regs[0])
|
||||
return {
|
||||
# output
|
||||
"f_outA": self.f_vco() / output_divider,
|
||||
"f_outB": self.f_vco() * 2,
|
||||
"output_divider": output_divider,
|
||||
# PLL parameters
|
||||
"f_vco": self.f_vco(),
|
||||
"pll_n": self.pll_n(),
|
||||
"pll_frac1": self.pll_frac1(),
|
||||
"pll_frac2": self.pll_frac2(),
|
||||
"pll_mod2": self.pll_mod2(),
|
||||
"prescaler": "4/5" if prescaler == 0 else "8/9",
|
||||
# reference / PFD
|
||||
"sysclk": self.sysclk,
|
||||
"ref_doubler": self.ref_doubler,
|
||||
"ref_divider": self.ref_divider,
|
||||
"ref_counter": self.ref_counter(),
|
||||
"f_pfd": self.f_pfd(),
|
||||
}
|
||||
|
||||
@portable
|
||||
def _init_registers(self):
|
||||
"""
|
||||
Initialize cached registers with sensible defaults.
|
||||
"""
|
||||
# fill with control bits
|
||||
self.regs = [int32(i) for i in range(ADF5355_NUM_REGS)]
|
||||
|
||||
# REG2
|
||||
# ====
|
||||
|
||||
# avoid divide-by-zero
|
||||
self.regs[2] |= ADF5355_REG2_AUX_MOD_LSB_VALUE(1)
|
||||
|
||||
# REG4
|
||||
# ====
|
||||
|
||||
# single-ended reference mode is recommended
|
||||
# for references up to 250 MHz, even if the signal is differential
|
||||
if self.sysclk <= 250 * MHz:
|
||||
self.regs[4] |= ADF5355_REG4_REF_MODE(0)
|
||||
else:
|
||||
self.regs[4] |= ADF5355_REG4_REF_MODE(1)
|
||||
|
||||
# phase detector polarity: positive
|
||||
self.regs[4] |= ADF5355_REG4_PD_POLARITY(1)
|
||||
|
||||
# charge pump current: 0.94 mA
|
||||
self.regs[4] |= ADF5355_REG4_CURRENT_SETTING(2)
|
||||
|
||||
# MUXOUT: digital lock detect
|
||||
self.regs[4] |= ADF5355_REG4_MUX_LOGIC(1) # 3v3 logic
|
||||
self.regs[4] |= ADF5355_REG4_MUXOUT(6)
|
||||
|
||||
# setup reference path
|
||||
if self.ref_doubler:
|
||||
self.regs[4] |= ADF5355_REG4_R_DOUBLER(1)
|
||||
|
||||
if self.ref_divider:
|
||||
self.regs[4] |= ADF5355_REG4_R_DIVIDER(1)
|
||||
|
||||
r = self._compute_reference_counter()
|
||||
self.regs[4] |= ADF5355_REG4_R_COUNTER(r)
|
||||
|
||||
# REG5
|
||||
# ====
|
||||
|
||||
# reserved values
|
||||
self.regs[5] = int32(0x800025)
|
||||
|
||||
# REG6
|
||||
# ====
|
||||
|
||||
# reserved values
|
||||
self.regs[6] = int32(0x14000006)
|
||||
|
||||
# enable negative bleed
|
||||
self.regs[6] |= ADF5355_REG6_NEGATIVE_BLEED(1)
|
||||
|
||||
# charge pump bleed current
|
||||
# self.regs[6] |= ADF5355_REG6_CP_BLEED_CURRENT(
|
||||
# int32(floor(24 * self.f_pfd / (61.44 * MHz)))
|
||||
# )
|
||||
|
||||
# direct feedback from VCO to N counter
|
||||
self.regs[6] |= ADF5355_REG6_FB_SELECT(1)
|
||||
|
||||
# mute until the PLL is locked
|
||||
self.regs[6] |= ADF5355_REG6_MUTE_TILL_LD(1)
|
||||
|
||||
# enable output A
|
||||
self.regs[6] |= ADF5355_REG6_RF_OUTPUT_A_ENABLE(1)
|
||||
|
||||
# set output A power to max power, is adjusted by extra attenuator
|
||||
self.regs[6] |= ADF5355_REG6_RF_OUTPUT_A_POWER(3) # +5 dBm
|
||||
|
||||
# REG7
|
||||
# ====
|
||||
|
||||
# reserved values
|
||||
self.regs[7] = int32(0x10000007)
|
||||
|
||||
# sync load-enable to reference
|
||||
self.regs[7] |= ADF5355_REG7_LE_SYNC(1)
|
||||
|
||||
# frac-N lock-detect precision: 12 ns
|
||||
self.regs[7] |= ADF5355_REG7_FRAC_N_LD_PRECISION(3)
|
||||
|
||||
# REG8
|
||||
# ====
|
||||
|
||||
# reserved values
|
||||
self.regs[8] = int32(0x102D0428)
|
||||
|
||||
# REG9
|
||||
# ====
|
||||
|
||||
# default timeouts (from eval software)
|
||||
self.regs[9] |= (
|
||||
ADF5355_REG9_SYNTH_LOCK_TIMEOUT(13)
|
||||
| ADF5355_REG9_AUTOCAL_TIMEOUT(31)
|
||||
| ADF5355_REG9_TIMEOUT(0x67)
|
||||
)
|
||||
|
||||
# REG10
|
||||
# =====
|
||||
|
||||
# reserved values
|
||||
self.regs[10] = int32(0xC0000A)
|
||||
|
||||
# ADC defaults (from eval software)
|
||||
self.regs[10] |= (
|
||||
ADF5355_REG10_ADC_ENABLE(1)
|
||||
| ADF5355_REG10_ADC_CLK_DIV(256)
|
||||
| ADF5355_REG10_ADC_CONV(1)
|
||||
)
|
||||
|
||||
# REG11
|
||||
# =====
|
||||
|
||||
# reserved values
|
||||
self.regs[11] = int32(0x61200B)
|
||||
|
||||
# REG12
|
||||
# =====
|
||||
|
||||
# reserved values
|
||||
self.regs[12] = int32(0x15FC)
|
||||
|
||||
@portable
|
||||
def _compute_pfd_frequency(self, r, d, t) -> TInt64:
|
||||
"""
|
||||
Calculate the PFD frequency from the given reference path parameters
|
||||
"""
|
||||
return int64(self.sysclk * ((1 + d) / (r * (1 + t))))
|
||||
|
||||
@portable
|
||||
def _compute_reference_counter(self) -> TInt32:
|
||||
"""
|
||||
Determine the reference counter R that maximizes the PFD frequency
|
||||
"""
|
||||
d = ADF5355_REG4_R_DOUBLER_GET(self.regs[4])
|
||||
t = ADF5355_REG4_R_DIVIDER_GET(self.regs[4])
|
||||
r = 1
|
||||
while self._compute_pfd_frequency(r, d, t) > ADF5355_MAX_FREQ_PFD:
|
||||
r += 1
|
||||
return int32(r)
|
||||
|
||||
|
||||
@portable
|
||||
def calculate_pll(f_vco: TInt64, f_pfd: TInt64):
|
||||
"""
|
||||
Calculate fractional-N PLL parameters such that
|
||||
|
||||
f_vco = f_pfd * (n + (frac1 + frac2/mod2) / mod1)
|
||||
|
||||
where
|
||||
mod1 = 16777216
|
||||
mod2 = 16383
|
||||
"""
|
||||
f_pfd = int64(f_pfd)
|
||||
f_vco = int64(f_vco)
|
||||
|
||||
# integral part
|
||||
n = int32(f_vco / f_pfd)
|
||||
r = f_vco / f_pfd - n
|
||||
|
||||
# main fractional part
|
||||
frac1 = int32(ADF5355_MODULUS1 * r)
|
||||
r = r * ADF5355_MODULUS1 - frac1
|
||||
|
||||
# auxiliary fractional part
|
||||
# FIXME: calculate optimal MOD2
|
||||
mod2 = ADF5355_MAX_MODULUS2
|
||||
frac2 = int32(r * mod2)
|
||||
|
||||
# split frac2, mod2
|
||||
frac2_msb, frac2_lsb = (frac2 >> 14) & 0x3FFF, frac2 & 0x3FFF
|
||||
mod2_msb, mod2_lsb = (mod2 >> 14) & 0x3FFF, mod2 & 0x3FFF
|
||||
|
||||
return n, frac1, (frac2_msb, frac2_lsb), (mod2_msb, mod2_lsb)
|
||||
|
|
|
@ -0,0 +1,742 @@
|
|||
# auto-generated, do not edit
|
||||
from artiq.language.core import portable
|
||||
from artiq.language.types import TInt32
|
||||
from numpy import int32
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG0_AUTOCAL_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 21) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG0_AUTOCAL(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 21)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG0_AUTOCAL_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 21)) | ((x & 0x1) << 21))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG0_INT_VALUE_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 4) & 0xFFFF)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG0_INT_VALUE(x: TInt32) -> TInt32:
|
||||
return int32((x & 0xFFFF) << 4)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG0_INT_VALUE_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0xFFFF << 4)) | ((x & 0xFFFF) << 4))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG0_PRESCALER_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 20) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG0_PRESCALER(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 20)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG0_PRESCALER_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 20)) | ((x & 0x1) << 20))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG1_MAIN_FRAC_VALUE_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 4) & 0xFFFFFF)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG1_MAIN_FRAC_VALUE(x: TInt32) -> TInt32:
|
||||
return int32((x & 0xFFFFFF) << 4)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG1_MAIN_FRAC_VALUE_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0xFFFFFF << 4)) | ((x & 0xFFFFFF) << 4))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG2_AUX_FRAC_LSB_VALUE_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 18) & 0x3FFF)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG2_AUX_FRAC_LSB_VALUE(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x3FFF) << 18)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG2_AUX_FRAC_LSB_VALUE_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x3FFF << 18)) | ((x & 0x3FFF) << 18))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG2_AUX_MOD_LSB_VALUE_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 4) & 0x3FFF)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG2_AUX_MOD_LSB_VALUE(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x3FFF) << 4)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG2_AUX_MOD_LSB_VALUE_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x3FFF << 4)) | ((x & 0x3FFF) << 4))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG3_PHASE_ADJUST_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 28) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG3_PHASE_ADJUST(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 28)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG3_PHASE_ADJUST_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 28)) | ((x & 0x1) << 28))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG3_PHASE_RESYNC_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 29) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG3_PHASE_RESYNC(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 29)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG3_PHASE_RESYNC_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 29)) | ((x & 0x1) << 29))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG3_PHASE_VALUE_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 4) & 0xFFFFFF)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG3_PHASE_VALUE(x: TInt32) -> TInt32:
|
||||
return int32((x & 0xFFFFFF) << 4)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG3_PHASE_VALUE_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0xFFFFFF << 4)) | ((x & 0xFFFFFF) << 4))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG3_SD_LOAD_RESET_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 30) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG3_SD_LOAD_RESET(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 30)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG3_SD_LOAD_RESET_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 30)) | ((x & 0x1) << 30))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_COUNTER_RESET_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 4) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_COUNTER_RESET(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 4)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_COUNTER_RESET_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 4)) | ((x & 0x1) << 4))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_CP_THREE_STATE_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 5) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_CP_THREE_STATE(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 5)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_CP_THREE_STATE_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 5)) | ((x & 0x1) << 5))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_CURRENT_SETTING_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 10) & 0xF)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_CURRENT_SETTING(x: TInt32) -> TInt32:
|
||||
return int32((x & 0xF) << 10)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_CURRENT_SETTING_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0xF << 10)) | ((x & 0xF) << 10))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_DOUBLE_BUFF_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 14) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_DOUBLE_BUFF(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 14)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_DOUBLE_BUFF_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 14)) | ((x & 0x1) << 14))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_MUX_LOGIC_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 8) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_MUX_LOGIC(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 8)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_MUX_LOGIC_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 8)) | ((x & 0x1) << 8))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_MUXOUT_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 27) & 0x7)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_MUXOUT(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x7) << 27)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_MUXOUT_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x7 << 27)) | ((x & 0x7) << 27))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_PD_POLARITY_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 7) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_PD_POLARITY(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 7)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_PD_POLARITY_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 7)) | ((x & 0x1) << 7))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_POWER_DOWN_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 6) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_POWER_DOWN(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 6)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_POWER_DOWN_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 6)) | ((x & 0x1) << 6))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_R_COUNTER_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 15) & 0x3FF)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_R_COUNTER(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x3FF) << 15)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_R_COUNTER_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x3FF << 15)) | ((x & 0x3FF) << 15))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_R_DIVIDER_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 25) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_R_DIVIDER(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 25)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_R_DIVIDER_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 25)) | ((x & 0x1) << 25))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_R_DOUBLER_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 26) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_R_DOUBLER(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 26)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_R_DOUBLER_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 26)) | ((x & 0x1) << 26))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_REF_MODE_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 9) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_REF_MODE(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 9)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG4_REF_MODE_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 9)) | ((x & 0x1) << 9))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_BLEED_POLARITY_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 31) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_BLEED_POLARITY(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 31)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_BLEED_POLARITY_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 31)) | ((x & 0x1) << 31))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_CP_BLEED_CURRENT_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 13) & 0xFF)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_CP_BLEED_CURRENT(x: TInt32) -> TInt32:
|
||||
return int32((x & 0xFF) << 13)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_CP_BLEED_CURRENT_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0xFF << 13)) | ((x & 0xFF) << 13))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_FB_SELECT_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 24) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_FB_SELECT(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 24)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_FB_SELECT_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 24)) | ((x & 0x1) << 24))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_GATE_BLEED_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 30) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_GATE_BLEED(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 30)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_GATE_BLEED_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 30)) | ((x & 0x1) << 30))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_MUTE_TILL_LD_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 11) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_MUTE_TILL_LD(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 11)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_MUTE_TILL_LD_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 11)) | ((x & 0x1) << 11))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_NEGATIVE_BLEED_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 29) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_NEGATIVE_BLEED(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 29)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_NEGATIVE_BLEED_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 29)) | ((x & 0x1) << 29))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_RF_DIVIDER_SELECT_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 21) & 0x7)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_RF_DIVIDER_SELECT(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x7) << 21)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_RF_DIVIDER_SELECT_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x7 << 21)) | ((x & 0x7) << 21))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_RF_OUTPUT_A_ENABLE_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 6) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_RF_OUTPUT_A_ENABLE(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 6)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_RF_OUTPUT_A_ENABLE_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 6)) | ((x & 0x1) << 6))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_RF_OUTPUT_A_POWER_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 4) & 0x3)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_RF_OUTPUT_A_POWER(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x3) << 4)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_RF_OUTPUT_A_POWER_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x3 << 4)) | ((x & 0x3) << 4))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_RF_OUTPUT_B_ENABLE_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 10) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_RF_OUTPUT_B_ENABLE(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 10)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG6_RF_OUTPUT_B_ENABLE_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 10)) | ((x & 0x1) << 10))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_FRAC_N_LD_PRECISION_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 5) & 0x3)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_FRAC_N_LD_PRECISION(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x3) << 5)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_FRAC_N_LD_PRECISION_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x3 << 5)) | ((x & 0x3) << 5))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_LD_CYCLE_COUNT_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 8) & 0x3)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_LD_CYCLE_COUNT(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x3) << 8)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_LD_CYCLE_COUNT_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x3 << 8)) | ((x & 0x3) << 8))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_LD_MODE_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 4) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_LD_MODE(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 4)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_LD_MODE_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 4)) | ((x & 0x1) << 4))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_LE_SEL_SYNC_EDGE_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 27) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_LE_SEL_SYNC_EDGE(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 27)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_LE_SEL_SYNC_EDGE_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 27)) | ((x & 0x1) << 27))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_LE_SYNC_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 25) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_LE_SYNC(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 25)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_LE_SYNC_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 25)) | ((x & 0x1) << 25))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_LOL_MODE_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 7) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_LOL_MODE(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 7)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG7_LOL_MODE_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 7)) | ((x & 0x1) << 7))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG9_AUTOCAL_TIMEOUT_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 9) & 0x1F)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG9_AUTOCAL_TIMEOUT(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1F) << 9)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG9_AUTOCAL_TIMEOUT_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1F << 9)) | ((x & 0x1F) << 9))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG9_SYNTH_LOCK_TIMEOUT_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 4) & 0x1F)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG9_SYNTH_LOCK_TIMEOUT(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1F) << 4)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG9_SYNTH_LOCK_TIMEOUT_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1F << 4)) | ((x & 0x1F) << 4))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG9_TIMEOUT_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 14) & 0x3FF)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG9_TIMEOUT(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x3FF) << 14)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG9_TIMEOUT_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x3FF << 14)) | ((x & 0x3FF) << 14))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG9_VCO_BAND_DIVISION_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 24) & 0xFF)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG9_VCO_BAND_DIVISION(x: TInt32) -> TInt32:
|
||||
return int32((x & 0xFF) << 24)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG9_VCO_BAND_DIVISION_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0xFF << 24)) | ((x & 0xFF) << 24))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG10_ADC_CLK_DIV_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 6) & 0xFF)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG10_ADC_CLK_DIV(x: TInt32) -> TInt32:
|
||||
return int32((x & 0xFF) << 6)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG10_ADC_CLK_DIV_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0xFF << 6)) | ((x & 0xFF) << 6))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG10_ADC_CONV_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 5) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG10_ADC_CONV(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 5)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG10_ADC_CONV_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 5)) | ((x & 0x1) << 5))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG10_ADC_ENABLE_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 4) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG10_ADC_ENABLE(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 4)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG10_ADC_ENABLE_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 4)) | ((x & 0x1) << 4))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG11_VCO_BAND_HOLD_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 24) & 0x1)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG11_VCO_BAND_HOLD(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x1) << 24)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG11_VCO_BAND_HOLD_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x1 << 24)) | ((x & 0x1) << 24))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG12_PHASE_RESYNC_CLK_VALUE_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 12) & 0xFFFFF)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG12_PHASE_RESYNC_CLK_VALUE(x: TInt32) -> TInt32:
|
||||
return int32((x & 0xFFFFF) << 12)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG12_PHASE_RESYNC_CLK_VALUE_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0xFFFFF << 12)) | ((x & 0xFFFFF) << 12))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG13_AUX_FRAC_MSB_VALUE_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 18) & 0x3FFF)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG13_AUX_FRAC_MSB_VALUE(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x3FFF) << 18)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG13_AUX_FRAC_MSB_VALUE_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x3FFF << 18)) | ((x & 0x3FFF) << 18))
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG13_AUX_MOD_MSB_VALUE_GET(reg: TInt32) -> TInt32:
|
||||
return int32((reg >> 4) & 0x3FFF)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG13_AUX_MOD_MSB_VALUE(x: TInt32) -> TInt32:
|
||||
return int32((x & 0x3FFF) << 4)
|
||||
|
||||
|
||||
@portable
|
||||
def ADF5355_REG13_AUX_MOD_MSB_VALUE_UPDATE(reg: TInt32, x: TInt32) -> TInt32:
|
||||
return int32((reg & ~(0x3FFF << 4)) | ((x & 0x3FFF) << 4))
|
||||
|
||||
|
||||
ADF5355_NUM_REGS = 14
|
|
@ -9,10 +9,16 @@ from numpy import int32
|
|||
from artiq.coredevice import spi2 as spi
|
||||
|
||||
|
||||
SPI_CONFIG = (0*spi.SPI_OFFLINE | 0*spi.SPI_END |
|
||||
0*spi.SPI_INPUT | 1*spi.SPI_CS_POLARITY |
|
||||
0*spi.SPI_CLK_POLARITY | 0*spi.SPI_CLK_PHASE |
|
||||
0*spi.SPI_LSB_FIRST | 0*spi.SPI_HALF_DUPLEX)
|
||||
SPI_CONFIG = (
|
||||
0 * spi.SPI_OFFLINE
|
||||
| 0 * spi.SPI_END
|
||||
| 0 * spi.SPI_INPUT
|
||||
| 1 * spi.SPI_CS_POLARITY
|
||||
| 0 * spi.SPI_CLK_POLARITY
|
||||
| 0 * spi.SPI_CLK_PHASE
|
||||
| 0 * spi.SPI_LSB_FIRST
|
||||
| 0 * spi.SPI_HALF_DUPLEX
|
||||
)
|
||||
|
||||
# SPI clock write and read dividers
|
||||
SPIT_WR = 4
|
||||
|
@ -24,41 +30,65 @@ WE = 1 << 24
|
|||
|
||||
|
||||
class Mirny:
|
||||
"""Mirny PLL-based RF generator.
|
||||
"""
|
||||
Mirny PLL-based RF generator.
|
||||
|
||||
:param spi_device: SPI bus device
|
||||
:param refclk: Reference clock (SMA, MMCX or on-board 100 MHz oscillator)
|
||||
frequency in Hz
|
||||
:param clk_sel: Reference clock selection.
|
||||
valid options are: 0 - internal 100MHz XO; 1 - front-panel SMA; 2 -
|
||||
internal MMCX
|
||||
:param core_device: Core device name (default: "core")
|
||||
"""
|
||||
|
||||
kernel_invariants = {"bus", "core"}
|
||||
|
||||
def __init__(self, dmgr, spi_device, core_device="core"):
|
||||
def __init__(self, dmgr, spi_device, refclk=100e6, clk_sel=0, core_device="core"):
|
||||
self.core = dmgr.get(core_device)
|
||||
self.bus = dmgr.get(spi_device)
|
||||
|
||||
self.refclk = refclk
|
||||
assert 10 <= self.refclk / 1e6 <= 600, "Invalid refclk"
|
||||
|
||||
self.clk_sel = clk_sel & 0b11
|
||||
assert 0 <= self.clk_sel <= 3, "Invalid clk_sel"
|
||||
|
||||
# TODO: support clk_div on v1.0 boards
|
||||
|
||||
@kernel
|
||||
def read_reg(self, addr):
|
||||
"""Read a register"""
|
||||
self.bus.set_config_mu(SPI_CONFIG | spi.SPI_INPUT | spi.SPI_END, 24,
|
||||
SPIT_RD, SPI_CS)
|
||||
self.bus.set_config_mu(
|
||||
SPI_CONFIG | spi.SPI_INPUT | spi.SPI_END, 24, SPIT_RD, SPI_CS
|
||||
)
|
||||
self.bus.write((addr << 25))
|
||||
return self.bus.read() & int32(0xffff)
|
||||
return self.bus.read() & int32(0xFFFF)
|
||||
|
||||
@kernel
|
||||
def write_reg(self, addr, data):
|
||||
"""Write a register"""
|
||||
self.bus.set_config_mu(SPI_CONFIG | spi.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
|
||||
def init(self):
|
||||
"""Initialize Mirny by reading the status register and verifying
|
||||
compatible hardware and protocol revisions"""
|
||||
reg0 = self.read_reg(0)
|
||||
if reg0 & 0b11 != 0b11:
|
||||
raise ValueError("Mirny HW_REV mismatch")
|
||||
if (reg0 >> 2) & 0b11 != 0b00:
|
||||
raise ValueError("Mirny PROTO_REV mismatch")
|
||||
delay(100*us) # slack
|
||||
def init(self, blind=False):
|
||||
"""
|
||||
Initialize and detect Mirny.
|
||||
|
||||
:param blind: Do not attempt to verify presence and compatibility.
|
||||
"""
|
||||
if not blind:
|
||||
reg0 = self.read_reg(0)
|
||||
if reg0 & 0b11 != 0b11:
|
||||
raise ValueError("Mirny HW_REV mismatch")
|
||||
if (reg0 >> 2) & 0b11 != 0b00:
|
||||
raise ValueError("Mirny PROTO_REV mismatch")
|
||||
delay(100 * us) # slack
|
||||
|
||||
# select clock source
|
||||
self.write_reg(1, (self.clk_sel << 4))
|
||||
delay(1000 * us)
|
||||
|
||||
@kernel
|
||||
def set_att_mu(self, channel, att):
|
||||
|
@ -74,8 +104,7 @@ class Mirny:
|
|||
"""Perform SPI write to a prefixed address"""
|
||||
self.bus.set_config_mu(SPI_CONFIG, 8, SPIT_WR, SPI_CS)
|
||||
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.SPI_END, length, SPIT_WR, SPI_CS)
|
||||
if length < 32:
|
||||
data <<= 32 - length
|
||||
self.bus.write(data)
|
||||
|
|
Loading…
Reference in New Issue