forked from M-Labs/artiq
phaser: dac and trf register maps, init code
This commit is contained in:
parent
3e036e365a
commit
fd5e221898
|
@ -0,0 +1,262 @@
|
||||||
|
class DAC34H84:
|
||||||
|
"""DAC34H84 settings and register map.
|
||||||
|
|
||||||
|
For possible values, documentation, and explanation, see the DAC datasheet
|
||||||
|
at https://www.ti.com/lit/pdf/slas751
|
||||||
|
"""
|
||||||
|
qmc_corr_ena = 0 # msb ab
|
||||||
|
qmc_offset_ena = 0 # msb ab
|
||||||
|
invsinc_ena = 0 # msb ab
|
||||||
|
interpolation = 1 # 2x
|
||||||
|
fifo_ena = 1
|
||||||
|
alarm_out_ena = 1
|
||||||
|
alarm_out_pol = 1
|
||||||
|
clkdiv_sync_ena = 1
|
||||||
|
|
||||||
|
iotest_ena = 0
|
||||||
|
cnt64_ena = 0
|
||||||
|
oddeven_parity = 0 # even
|
||||||
|
single_parity_ena = 1
|
||||||
|
dual_parity_ena = 0
|
||||||
|
rev_interface = 0
|
||||||
|
dac_complement = 0b0000 # msb A
|
||||||
|
alarm_fifo = 0b111 # msb 2-away
|
||||||
|
|
||||||
|
dacclkgone_ena = 1
|
||||||
|
dataclkgone_ena = 1
|
||||||
|
collisiongone_ena = 1
|
||||||
|
sif4_ena = 1
|
||||||
|
mixer_ena = 0
|
||||||
|
mixer_gain = 1
|
||||||
|
nco_ena = 0
|
||||||
|
revbus = 0
|
||||||
|
twos = 1
|
||||||
|
|
||||||
|
coarse_dac = 0xa # 20.6 mA, 0-15
|
||||||
|
sif_txenable = 0
|
||||||
|
|
||||||
|
mask_alarm_from_zerochk = 0
|
||||||
|
mask_alarm_fifo_collision = 0
|
||||||
|
mask_alarm_fifo_1away = 0
|
||||||
|
mask_alarm_fifo_2away = 0
|
||||||
|
mask_alarm_dacclk_gone = 0
|
||||||
|
mask_alarm_dataclk_gone = 0
|
||||||
|
mask_alarm_output_gone = 0
|
||||||
|
mask_alarm_from_iotest = 0
|
||||||
|
mask_alarm_from_pll = 0
|
||||||
|
mask_alarm_parity = 0b0000 # msb a
|
||||||
|
|
||||||
|
qmc_offseta = 0 # 12b
|
||||||
|
fifo_offset = 2 # 0-7
|
||||||
|
qmc_offsetb = 0 # 12b
|
||||||
|
|
||||||
|
qmc_offsetc = 0 # 12b
|
||||||
|
|
||||||
|
qmc_offsetd = 0 # 12b
|
||||||
|
|
||||||
|
qmc_gaina = 0 # 11b
|
||||||
|
|
||||||
|
cmix_fs8 = 0
|
||||||
|
cmix_fs4 = 0
|
||||||
|
cmix_fs2 = 0
|
||||||
|
cmix_nfs4 = 0
|
||||||
|
qmc_gainb = 0 # 11b
|
||||||
|
|
||||||
|
qmc_gainc = 0 # 11b
|
||||||
|
|
||||||
|
output_delayab = 0b00
|
||||||
|
output_delaycd = 0b00
|
||||||
|
qmc_gaind = 0 # 11b
|
||||||
|
|
||||||
|
qmc_phaseab = 0 # 12b
|
||||||
|
|
||||||
|
qmc_phasecd = 0 # 12b
|
||||||
|
|
||||||
|
pll_reset = 0
|
||||||
|
pll_ndivsync_ena = 1
|
||||||
|
pll_ena = 1
|
||||||
|
pll_cp = 0b01 # single charge pump
|
||||||
|
pll_p = 0b100 # p=4
|
||||||
|
|
||||||
|
pll_m2 = 1 # x2
|
||||||
|
pll_m = 8 # m = 8
|
||||||
|
pll_n = 0b0001 # n = 2
|
||||||
|
pll_vcotune = 0b01
|
||||||
|
|
||||||
|
pll_vco = 0x3f # 4 GHz
|
||||||
|
bias_sleep = 0
|
||||||
|
tsense_sleep = 0
|
||||||
|
pll_sleep = 0
|
||||||
|
clkrecv_sleep = 0
|
||||||
|
dac_sleep = 0b0000 # msb a
|
||||||
|
|
||||||
|
extref_ena = 0
|
||||||
|
fuse_sleep = 1
|
||||||
|
atest = 0b00000 # atest mode
|
||||||
|
|
||||||
|
syncsel_qmcoffsetab = 0b1001 # sif_sync and register write
|
||||||
|
syncsel_qmcoffsetcd = 0b1001 # sif_sync and register write
|
||||||
|
syncsel_qmccorrab = 0b1001 # sif_sync and register write
|
||||||
|
syncsel_qmccorrcd = 0b1001 # sif_sync and register write
|
||||||
|
|
||||||
|
syncsel_mixerab = 0b1001 # sif_sync and register write
|
||||||
|
syncsel_mixercd = 0b1001 # sif_sync and register write
|
||||||
|
syncsel_nco = 0b1000 # sif_sync
|
||||||
|
syncsel_fifo_input = 0b10 # external lvds istr
|
||||||
|
sif_sync = 1
|
||||||
|
|
||||||
|
syncsel_fifoin = 0b0010 # istr
|
||||||
|
syncsel_fifoout = 0b0100 # ostr
|
||||||
|
clkdiv_sync_sel = 0 # ostr
|
||||||
|
|
||||||
|
path_a_sel = 0b00
|
||||||
|
path_b_sel = 0b01
|
||||||
|
path_c_sel = 0b10
|
||||||
|
path_d_sel = 0b11
|
||||||
|
# reverse dacs (DCBA) for spectral inversion and layout
|
||||||
|
dac_a_sel = 0b11
|
||||||
|
dac_b_sel = 0b10
|
||||||
|
dac_c_sel = 0b01
|
||||||
|
dac_d_sel = 0b00
|
||||||
|
|
||||||
|
dac_sleep_en = 0b1111 # msb a
|
||||||
|
clkrecv_sleep_en = 1
|
||||||
|
pll_sleep_en = 1
|
||||||
|
lvds_data_sleep_en = 1
|
||||||
|
lvds_control_sleep_en = 1
|
||||||
|
temp_sense_sleep_en = 1
|
||||||
|
bias_sleep_en = 1
|
||||||
|
|
||||||
|
data_dly = 2
|
||||||
|
clk_dly = 0
|
||||||
|
|
||||||
|
ostrtodig_sel = 0
|
||||||
|
ramp_ena = 0
|
||||||
|
sifdac_ena = 0
|
||||||
|
|
||||||
|
grp_delaya = 0x00
|
||||||
|
grp_delayb = 0x00
|
||||||
|
|
||||||
|
grp_delayc = 0x00
|
||||||
|
grp_delayd = 0x00
|
||||||
|
|
||||||
|
sifdac = 0
|
||||||
|
|
||||||
|
def __init__(self, updates=None):
|
||||||
|
if updates is None:
|
||||||
|
return
|
||||||
|
for key, value in updates.items():
|
||||||
|
if not hasattr(self, key):
|
||||||
|
raise KeyError("invalid setting", key)
|
||||||
|
setattr(self, key, value)
|
||||||
|
|
||||||
|
def get_mmap(self):
|
||||||
|
mmap = []
|
||||||
|
mmap.append(
|
||||||
|
(0x00 << 16) |
|
||||||
|
(self.qmc_offset_ena << 14) | (self.qmc_corr_ena << 12) |
|
||||||
|
(self.interpolation << 8) | (self.fifo_ena << 7) |
|
||||||
|
(self.alarm_out_ena << 4) | (self.alarm_out_pol << 3) |
|
||||||
|
(self.clkdiv_sync_ena << 2) | (self.invsinc_ena << 0))
|
||||||
|
mmap.append(
|
||||||
|
(0x01 << 16) |
|
||||||
|
(self.iotest_ena << 15) | (self.cnt64_ena << 12) |
|
||||||
|
(self.oddeven_parity << 11) | (self.single_parity_ena << 10) |
|
||||||
|
(self.dual_parity_ena << 9) | (self.rev_interface << 8) |
|
||||||
|
(self.dac_complement << 4) | (self.alarm_fifo << 1))
|
||||||
|
mmap.append(
|
||||||
|
(0x02 << 16) |
|
||||||
|
(self.dacclkgone_ena << 14) | (self.dataclkgone_ena << 13) |
|
||||||
|
(self.collisiongone_ena << 12) | (self.sif4_ena << 7) |
|
||||||
|
(self.mixer_ena << 6) | (self.mixer_gain << 5) |
|
||||||
|
(self.nco_ena << 4) | (self.revbus << 3) | (self.twos << 1))
|
||||||
|
mmap.append((0x03 << 16) | (self.coarse_dac << 12) | (self.sif_txenable << 0))
|
||||||
|
mmap.append(
|
||||||
|
(0x07 << 16) |
|
||||||
|
(self.mask_alarm_from_zerochk << 15) | (1 << 14) |
|
||||||
|
(self.mask_alarm_fifo_collision << 13) |
|
||||||
|
(self.mask_alarm_fifo_1away << 12) |
|
||||||
|
(self.mask_alarm_fifo_2away << 11) |
|
||||||
|
(self.mask_alarm_dacclk_gone << 10) |
|
||||||
|
(self.mask_alarm_dataclk_gone << 9) |
|
||||||
|
(self.mask_alarm_output_gone << 8) |
|
||||||
|
(self.mask_alarm_from_iotest << 7) | (1 << 6) |
|
||||||
|
(self.mask_alarm_from_pll << 5) | (self.mask_alarm_parity << 1))
|
||||||
|
mmap.append(
|
||||||
|
(0x08 << 16) | (self.qmc_offseta << 0))
|
||||||
|
mmap.append(
|
||||||
|
(0x09 << 16) | (self.fifo_offset << 13) | (self.qmc_offsetb << 0))
|
||||||
|
mmap.append((0x0a << 16) | (self.qmc_offsetc << 0))
|
||||||
|
mmap.append((0x0b << 16) | (self.qmc_offsetd << 0))
|
||||||
|
mmap.append((0x0c << 16) | (self.qmc_gaina << 0))
|
||||||
|
mmap.append(
|
||||||
|
(0x0d << 16) |
|
||||||
|
(self.cmix_fs8 << 15) | (self.cmix_fs4 << 14) |
|
||||||
|
(self.cmix_fs2 << 12) | (self.cmix_nfs4 << 11) |
|
||||||
|
(self.qmc_gainb << 0))
|
||||||
|
mmap.append((0x0e << 16) | (self.qmc_gainc << 0))
|
||||||
|
mmap.append(
|
||||||
|
(0x0f << 16) |
|
||||||
|
(self.output_delayab << 14) | (self.output_delaycd << 12) |
|
||||||
|
(self.qmc_gaind << 0))
|
||||||
|
mmap.append((0x10 << 16) | (self.qmc_phaseab << 0))
|
||||||
|
mmap.append((0x11 << 16) | (self.qmc_phasecd << 0))
|
||||||
|
mmap.append(
|
||||||
|
(0x18 << 16) |
|
||||||
|
(0b001 << 13) | (self.pll_reset << 12) |
|
||||||
|
(self.pll_ndivsync_ena << 11) | (self.pll_ena << 10) |
|
||||||
|
(self.pll_cp << 6) | (self.pll_p << 3))
|
||||||
|
mmap.append(
|
||||||
|
(0x19 << 16) |
|
||||||
|
(self.pll_m2 << 15) | (self.pll_m << 8) | (self.pll_n << 4) |
|
||||||
|
(self.pll_vcotune << 2))
|
||||||
|
mmap.append(
|
||||||
|
(0x1a << 16) |
|
||||||
|
(self.pll_vco << 10) | (self.bias_sleep << 7) |
|
||||||
|
(self.tsense_sleep << 6) |
|
||||||
|
(self.pll_sleep << 5) | (self.clkrecv_sleep << 4) |
|
||||||
|
(self.dac_sleep << 0))
|
||||||
|
mmap.append(
|
||||||
|
(0x1b << 16) |
|
||||||
|
(self.extref_ena << 15) | (self.fuse_sleep << 11) |
|
||||||
|
(self.atest << 0))
|
||||||
|
mmap.append(
|
||||||
|
(0x1e << 16) |
|
||||||
|
(self.syncsel_qmcoffsetab << 12) |
|
||||||
|
(self.syncsel_qmcoffsetcd << 8) |
|
||||||
|
(self.syncsel_qmccorrab << 4) |
|
||||||
|
(self.syncsel_qmccorrcd << 0))
|
||||||
|
mmap.append(
|
||||||
|
(0x1f << 16) |
|
||||||
|
(self.syncsel_mixerab << 12) | (self.syncsel_mixercd << 8) |
|
||||||
|
(self.syncsel_nco << 4) | (self.syncsel_fifo_input << 2) |
|
||||||
|
(self.sif_sync << 1))
|
||||||
|
mmap.append(
|
||||||
|
(0x20 << 16) |
|
||||||
|
(self.syncsel_fifoin << 12) | (self.syncsel_fifoout << 8) |
|
||||||
|
(self.clkdiv_sync_sel << 0))
|
||||||
|
mmap.append(
|
||||||
|
(0x22 << 16) |
|
||||||
|
(self.path_a_sel << 14) | (self.path_b_sel << 12) |
|
||||||
|
(self.path_c_sel << 10) | (self.path_d_sel << 8) |
|
||||||
|
(self.dac_a_sel << 6) | (self.dac_b_sel << 4) |
|
||||||
|
(self.dac_c_sel << 2) | (self.dac_d_sel << 0))
|
||||||
|
mmap.append(
|
||||||
|
(0x23 << 16) |
|
||||||
|
(self.dac_sleep_en << 12) | (self.clkrecv_sleep_en << 11) |
|
||||||
|
(self.pll_sleep_en << 10) | (self.lvds_data_sleep_en << 9) |
|
||||||
|
(self.lvds_control_sleep_en << 8) |
|
||||||
|
(self.temp_sense_sleep_en << 7) | (1 << 6) |
|
||||||
|
(self.bias_sleep_en << 5) | (0x1f << 0))
|
||||||
|
mmap.append(
|
||||||
|
(0x24 << 16) | (self.data_dly << 13) | (self.clk_dly << 10))
|
||||||
|
mmap.append(
|
||||||
|
(0x2d << 16) |
|
||||||
|
(self.ostrtodig_sel << 14) | (self.ramp_ena << 13) |
|
||||||
|
(0x002 << 1) | (self.sifdac_ena << 0))
|
||||||
|
mmap.append(
|
||||||
|
(0x2e << 16) | (self.grp_delaya << 8) | (self.grp_delayb << 0))
|
||||||
|
mmap.append(
|
||||||
|
(0x2f << 16) | (self.grp_delayc << 8) | (self.grp_delayd << 0))
|
||||||
|
mmap.append((0x30 << 16) | self.sifdac)
|
||||||
|
return mmap
|
|
@ -2,6 +2,8 @@ from artiq.language.core import kernel, delay_mu, delay
|
||||||
from artiq.coredevice.rtio import rtio_output, rtio_input_data
|
from artiq.coredevice.rtio import rtio_output, rtio_input_data
|
||||||
from artiq.language.units import us, ns, ms, MHz, dB
|
from artiq.language.units import us, ns, ms, MHz, dB
|
||||||
from artiq.language.types import TInt32
|
from artiq.language.types import TInt32
|
||||||
|
from artiq.coredevice.dac34h84 import DAC34H84
|
||||||
|
from artiq.coredevice.trf372017 import TRF372017
|
||||||
|
|
||||||
|
|
||||||
PHASER_BOARD_ID = 19
|
PHASER_BOARD_ID = 19
|
||||||
|
@ -106,10 +108,22 @@ class Phaser:
|
||||||
configured through a shared SPI bus that is accessed and controlled via
|
configured through a shared SPI bus that is accessed and controlled via
|
||||||
FPGA registers.
|
FPGA registers.
|
||||||
|
|
||||||
|
.. note:: Various register settings of the DAC and the quadrature
|
||||||
|
upconverters are available to be modified through the `dac`, `trf0`,
|
||||||
|
`trf1` dictionaries. These can be set through the device database
|
||||||
|
(`device_db.py`). The settings are frozen during instantiation of the
|
||||||
|
class and applied during `init()`. See the :class:`DAC34H84` and
|
||||||
|
:class:`TRF372017` source for details.
|
||||||
|
|
||||||
:param channel: Base RTIO channel number
|
:param channel: Base RTIO channel number
|
||||||
:param core_device: Core device name (default: "core")
|
:param core_device: Core device name (default: "core")
|
||||||
:param miso_delay: Fastlink MISO signal delay to account for cable
|
:param miso_delay: Fastlink MISO signal delay to account for cable
|
||||||
and buffer round trip. This might be automated later.
|
and buffer round trip. Tuning this might be automated later.
|
||||||
|
:param dac: DAC34H84 DAC settings as a dictionary.
|
||||||
|
:param trf0: Channel 0 TRF372017 quadrature upconverter settings as a
|
||||||
|
dictionary.
|
||||||
|
:param trf1: Channel 1 TRF372017 quadrature upconverter settings as a
|
||||||
|
dictionary.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
|
|
||||||
|
@ -117,9 +131,11 @@ class Phaser:
|
||||||
To access oscillators, digital upconverters, PLL/VCO analog
|
To access oscillators, digital upconverters, PLL/VCO analog
|
||||||
quadrature upconverters and attenuators.
|
quadrature upconverters and attenuators.
|
||||||
"""
|
"""
|
||||||
kernel_invariants = {"core", "channel_base", "t_frame", "miso_delay"}
|
kernel_invariants = {"core", "channel_base", "t_frame", "miso_delay",
|
||||||
|
"dac_mmap"}
|
||||||
|
|
||||||
def __init__(self, dmgr, channel_base, miso_delay=1, core_device="core"):
|
def __init__(self, dmgr, channel_base, miso_delay=1, core_device="core",
|
||||||
|
dac=None, trf0=None, trf1=None):
|
||||||
self.channel_base = channel_base
|
self.channel_base = channel_base
|
||||||
self.core = dmgr.get(core_device)
|
self.core = dmgr.get(core_device)
|
||||||
# TODO: auto-align miso-delay in phy
|
# TODO: auto-align miso-delay in phy
|
||||||
|
@ -129,14 +145,18 @@ class Phaser:
|
||||||
assert self.core.ref_period == 1*ns
|
assert self.core.ref_period == 1*ns
|
||||||
self.t_frame = 10*8*4
|
self.t_frame = 10*8*4
|
||||||
|
|
||||||
self.channel = [PhaserChannel(self, ch) for ch in range(2)]
|
self.dac_mmap = DAC34H84(dac).get_mmap()
|
||||||
|
|
||||||
|
self.channel = [PhaserChannel(self, ch, trf)
|
||||||
|
for ch, trf in enumerate([trf0, trf1])]
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def init(self, clk_sel=0):
|
def init(self, clk_sel=0):
|
||||||
"""Initialize the board.
|
"""Initialize the board.
|
||||||
|
|
||||||
Verifies board and chip presence, resets components, performs communication
|
Verifies board and chip presence, resets components, performs
|
||||||
and configuration tests and establishes initial conditions.
|
communication and configuration tests and establishes initial
|
||||||
|
conditions.
|
||||||
|
|
||||||
:param clk_sel: Select the external SMA clock input (1 or 0)
|
:param clk_sel: Select the external SMA clock input (1 or 0)
|
||||||
"""
|
"""
|
||||||
|
@ -145,18 +165,28 @@ class Phaser:
|
||||||
raise ValueError("invalid board id")
|
raise ValueError("invalid board id")
|
||||||
delay(20*us) # slack
|
delay(20*us) # slack
|
||||||
|
|
||||||
|
hw_rev = self.read8(PHASER_ADDR_HW_REV)
|
||||||
|
delay(.1*ms) # slack
|
||||||
|
has_upconverter = hw_rev & PHASER_HW_REV_VARIANT
|
||||||
|
|
||||||
|
gw_rev = self.read8(PHASER_ADDR_GW_REV)
|
||||||
|
delay(.1*ms) # slack
|
||||||
|
|
||||||
# allow a few errors during startup and alignment since boot
|
# allow a few errors during startup and alignment since boot
|
||||||
if self.get_crc_err() > 20:
|
if self.get_crc_err() > 20:
|
||||||
raise ValueError("large number of frame CRC errors")
|
raise ValueError("large number of frame CRC errors")
|
||||||
delay(.1*ms) # slack
|
delay(.1*ms) # slack
|
||||||
|
|
||||||
# reset
|
# reset
|
||||||
self.set_cfg(dac_resetb=0, att0_rstn=0, att1_rstn=0, dac_txena=0)
|
self.set_cfg(dac_resetb=0, dac_sleep=1, att0_rstn=0, att1_rstn=0,
|
||||||
|
dac_txena=0)
|
||||||
self.set_leds(0x00)
|
self.set_leds(0x00)
|
||||||
self.set_fan_mu(0)
|
self.set_fan_mu(0)
|
||||||
self.set_cfg(clk_sel=clk_sel, dac_txena=0) # bring everything out of reset
|
# bring everything out of reset, keep tx off
|
||||||
|
self.set_cfg(clk_sel=clk_sel, dac_txena=0)
|
||||||
|
|
||||||
# TODO: crossing dac_clk (125 MHz) edges with sync_dly (0-7 ns)
|
# TODO: crossing dac_clk (125 MHz) edges with sync_dly (0-7 ns)
|
||||||
# should change the optimal fifo_offset
|
# should change the optimal fifo_offset by 4
|
||||||
self.set_sync_dly(4)
|
self.set_sync_dly(4)
|
||||||
delay(.1*ms) # slack
|
delay(.1*ms) # slack
|
||||||
|
|
||||||
|
@ -174,6 +204,10 @@ class Phaser:
|
||||||
if t < 10 or t > 90:
|
if t < 10 or t > 90:
|
||||||
raise ValueError("DAC temperature out of bounds")
|
raise ValueError("DAC temperature out of bounds")
|
||||||
|
|
||||||
|
for data in self.dac_mmap:
|
||||||
|
self.dac_write(data >> 16, data)
|
||||||
|
delay(.1*ms)
|
||||||
|
|
||||||
patterns = [
|
patterns = [
|
||||||
[0xf05a, 0x05af, 0x5af0, 0xaf05], # test channel/iq/byte/nibble
|
[0xf05a, 0x05af, 0x5af0, 0xaf05], # test channel/iq/byte/nibble
|
||||||
[0x7a7a, 0xb6b6, 0xeaea, 0x4545], # datasheet pattern a
|
[0x7a7a, 0xb6b6, 0xeaea, 0x4545], # datasheet pattern a
|
||||||
|
@ -183,206 +217,25 @@ class Phaser:
|
||||||
# FPGA+board+DAC skews. There is plenty of margin (>= 250 ps
|
# FPGA+board+DAC skews. There is plenty of margin (>= 250 ps
|
||||||
# either side) and no need to tune at runtime.
|
# either side) and no need to tune at runtime.
|
||||||
# Parity provides another level of safety.
|
# Parity provides another level of safety.
|
||||||
for dly in [-2]: # range(-7, 8)
|
for i in range(len(patterns)):
|
||||||
if dly < 0: # use data delay, else use clock delay
|
delay(.5*ms)
|
||||||
dly = -dly << 3
|
errors = self.dac_iotest(patterns[i])
|
||||||
self.dac_write(0x24, dly << 10)
|
if errors:
|
||||||
for i in range(len(patterns)):
|
raise ValueError("DAC iotest failure")
|
||||||
errors = self.dac_iotest(patterns[i])
|
|
||||||
if errors:
|
|
||||||
raise ValueError("DAC iotest failure")
|
|
||||||
delay(.5*ms)
|
|
||||||
|
|
||||||
qmc_corr_ena = 0 # msb ab
|
|
||||||
qmc_offset_ena = 0 # msb ab
|
|
||||||
invsinc_ena = 0 # msb ab
|
|
||||||
|
|
||||||
interpolation = 1 # 2x
|
|
||||||
fifo_ena = 1
|
|
||||||
alarm_out_ena = 1
|
|
||||||
alarm_out_pol = 1
|
|
||||||
clkdiv_sync_ena = 1
|
|
||||||
self.dac_write(0x00,
|
|
||||||
(qmc_offset_ena << 14) | (qmc_corr_ena << 12) |
|
|
||||||
(interpolation << 8) | (fifo_ena << 7) |
|
|
||||||
(alarm_out_ena << 4) | (alarm_out_pol << 3) |
|
|
||||||
(clkdiv_sync_ena << 2) | (invsinc_ena << 0))
|
|
||||||
iotest_ena = 0
|
|
||||||
cnt64_ena = 0
|
|
||||||
oddeven_parity = 0 # even
|
|
||||||
single_parity_ena = 1
|
|
||||||
dual_parity_ena = 0
|
|
||||||
rev_interface = 0
|
|
||||||
dac_complement = 0b0000 # msb A
|
|
||||||
alarm_fifo = 0b111 # msb 2-away
|
|
||||||
self.dac_write(0x01,
|
|
||||||
(iotest_ena << 15) | (cnt64_ena << 12) |
|
|
||||||
(oddeven_parity << 11) | (single_parity_ena << 10) |
|
|
||||||
(dual_parity_ena << 9) | (rev_interface << 8) |
|
|
||||||
(dac_complement << 4) | (alarm_fifo << 1))
|
|
||||||
dacclkgone_ena = 1
|
|
||||||
dataclkgone_ena = 1
|
|
||||||
collisiongone_ena = 1
|
|
||||||
sif4_ena = 1
|
|
||||||
mixer_ena = 0
|
|
||||||
mixer_gain = 1
|
|
||||||
nco_ena = 0
|
|
||||||
revbus = 0
|
|
||||||
twos = 1
|
|
||||||
self.dac_write(0x02,
|
|
||||||
(dacclkgone_ena << 14) | (dataclkgone_ena << 13) |
|
|
||||||
(collisiongone_ena << 12) | (sif4_ena << 7) |
|
|
||||||
(mixer_ena << 6) | (mixer_gain << 5) |
|
|
||||||
(nco_ena << 4) | (revbus << 3) | (twos << 1))
|
|
||||||
coarse_dac = 0xa # 20.6 mA, 0-15
|
|
||||||
sif_txenable = 0
|
|
||||||
self.dac_write(0x03, (coarse_dac << 12) | (sif_txenable << 0))
|
|
||||||
mask_alarm_from_zerochk = 0
|
|
||||||
mask_alarm_fifo_collision = 0
|
|
||||||
mask_alarm_fifo_1away = 0
|
|
||||||
mask_alarm_fifo_2away = 0
|
|
||||||
mask_alarm_dacclk_gone = 0
|
|
||||||
mask_alarm_dataclk_gone = 0
|
|
||||||
mask_alarm_output_gone = 0
|
|
||||||
mask_alarm_from_iotest = 0
|
|
||||||
mask_alarm_from_pll = 0
|
|
||||||
mask_alarm_parity = 0b0000 # msb a
|
|
||||||
self.dac_write(0x07,
|
|
||||||
(mask_alarm_from_zerochk << 15) | (1 << 14) |
|
|
||||||
(mask_alarm_fifo_collision << 13) | (mask_alarm_fifo_1away << 12) |
|
|
||||||
(mask_alarm_fifo_2away << 11) | (mask_alarm_dacclk_gone << 10) |
|
|
||||||
(mask_alarm_dataclk_gone << 9) | (mask_alarm_output_gone << 8) |
|
|
||||||
(mask_alarm_from_iotest << 7) | (1 << 6) |
|
|
||||||
(mask_alarm_from_pll << 5) | (mask_alarm_parity << 1))
|
|
||||||
qmc_offseta = 0 # 12b
|
|
||||||
self.dac_write(0x08, qmc_offseta)
|
|
||||||
fifo_offset = 2 # 0-7
|
|
||||||
qmc_offsetb = 0 # 12b
|
|
||||||
self.dac_write(0x09, (fifo_offset << 13) | qmc_offsetb)
|
|
||||||
qmc_offsetc = 0 # 12b
|
|
||||||
self.dac_write(0x0a, qmc_offsetc)
|
|
||||||
qmc_offsetd = 0 # 12b
|
|
||||||
self.dac_write(0x0b, qmc_offsetd)
|
|
||||||
qmc_gaina = 0 # 11b
|
|
||||||
self.dac_write(0x0c, qmc_gaina)
|
|
||||||
cmix_fs8 = 0
|
|
||||||
cmix_fs4 = 0
|
|
||||||
cmix_fs2 = 0
|
|
||||||
cmix_nfs4 = 0
|
|
||||||
qmc_gainb = 0 # 11b
|
|
||||||
self.dac_write(0x0d,
|
|
||||||
(cmix_fs8 << 15) | (cmix_fs4 << 14) | (cmix_fs2 << 12) |
|
|
||||||
(cmix_nfs4 << 11) | qmc_gainb)
|
|
||||||
qmc_gainc = 0 # 11b
|
|
||||||
self.dac_write(0x0e, qmc_gainc)
|
|
||||||
output_delayab = 0b00
|
|
||||||
output_delaycd = 0b00
|
|
||||||
qmc_gaind = 0 # 11b
|
|
||||||
self.dac_write(0x0f, (output_delayab << 14) | (output_delaycd << 12) |
|
|
||||||
qmc_gaind)
|
|
||||||
qmc_phaseab = 0 # 12b
|
|
||||||
self.dac_write(0x10, qmc_phaseab)
|
|
||||||
qmc_phasecd = 0 # 12b
|
|
||||||
self.dac_write(0x11, qmc_phasecd)
|
|
||||||
pll_reset = 0
|
|
||||||
pll_ndivsync_ena = 1
|
|
||||||
pll_ena = 1
|
|
||||||
pll_cp = 0b01 # single charge pump
|
|
||||||
pll_p = 0b100 # p=4
|
|
||||||
self.dac_write(0x18,
|
|
||||||
(0b001 << 13) | (pll_reset << 12) |
|
|
||||||
(pll_ndivsync_ena << 11) | (pll_ena << 10) |
|
|
||||||
(pll_cp << 6) | (pll_p << 3))
|
|
||||||
pll_m2 = 1 # x2
|
|
||||||
pll_m = 8 # m = 8
|
|
||||||
pll_n = 0b0001 # n = 2
|
|
||||||
pll_vcotune = 0b01
|
|
||||||
self.dac_write(0x19,
|
|
||||||
(pll_m2 << 15) | (pll_m << 8) | (pll_n << 4) | (pll_vcotune << 2))
|
|
||||||
delay(.5*ms) # slack
|
|
||||||
pll_vco = 0x3f # 4 GHz
|
|
||||||
bias_sleep = 0
|
|
||||||
tsense_sleep = 0
|
|
||||||
pll_sleep = 0
|
|
||||||
clkrecv_sleep = 0
|
|
||||||
dac_sleep = 0b0000 # msb a
|
|
||||||
self.dac_write(0x1a,
|
|
||||||
(pll_vco << 10) | (bias_sleep << 7) | (tsense_sleep << 6) |
|
|
||||||
(pll_sleep << 5) | (clkrecv_sleep << 4) | (dac_sleep << 0))
|
|
||||||
extref_ena = 0
|
|
||||||
fuse_sleep = 1
|
|
||||||
atest = 0b00000 # atest mode
|
|
||||||
self.dac_write(0x1b,
|
|
||||||
(extref_ena << 15) | (fuse_sleep << 11) | (atest << 0))
|
|
||||||
syncsel_qmcoffsetab = 0b1001 # sif_sync and register write
|
|
||||||
syncsel_qmcoffsetcd = 0b1001 # sif_sync and register write
|
|
||||||
syncsel_qmccorrab = 0b1001 # sif_sync and register write
|
|
||||||
syncsel_qmccorrcd = 0b1001 # sif_sync and register write
|
|
||||||
self.dac_write(0x1e,
|
|
||||||
(syncsel_qmcoffsetab << 12) | (syncsel_qmcoffsetcd << 8) |
|
|
||||||
(syncsel_qmccorrab << 4) | (syncsel_qmccorrcd << 0))
|
|
||||||
syncsel_mixerab = 0b1001 # sif_sync and register write
|
|
||||||
syncsel_mixercd = 0b1001 # sif_sync and register write
|
|
||||||
syncsel_nco = 0b1000 # sif_sync
|
|
||||||
syncsel_fifo_input = 0b10 # external lvds istr
|
|
||||||
sif_sync = 1
|
|
||||||
self.dac_write(0x1e,
|
|
||||||
(syncsel_mixerab << 12) | (syncsel_mixercd << 8) |
|
|
||||||
(syncsel_nco << 4) | (syncsel_fifo_input << 2) |
|
|
||||||
(sif_sync << 1))
|
|
||||||
syncsel_fifoin = 0b0010 # istr
|
|
||||||
syncsel_fifoout = 0b0100 # ostr
|
|
||||||
clkdiv_sync_sel = 0 # ostr
|
|
||||||
self.dac_write(0x20,
|
|
||||||
(syncsel_fifoin << 12) | (syncsel_fifoout << 8) |
|
|
||||||
(clkdiv_sync_sel << 0))
|
|
||||||
path_a_sel = 0b00
|
|
||||||
path_b_sel = 0b01
|
|
||||||
path_c_sel = 0b10
|
|
||||||
path_d_sel = 0b11
|
|
||||||
# reverse dacs (DCBA) for spectral inversion and layout
|
|
||||||
dac_a_sel = 0b11
|
|
||||||
dac_b_sel = 0b10
|
|
||||||
dac_c_sel = 0b01
|
|
||||||
dac_d_sel = 0b00
|
|
||||||
self.dac_write(0x22,
|
|
||||||
(path_a_sel << 14) | (path_b_sel << 12) |
|
|
||||||
(path_c_sel << 10) | (path_d_sel << 8) |
|
|
||||||
(dac_a_sel << 6) | (dac_b_sel << 4) |
|
|
||||||
(dac_c_sel << 2) | (dac_d_sel << 0))
|
|
||||||
dac_sleep_en = 0b1111 # msb a
|
|
||||||
clkrecv_sleep_en = 1
|
|
||||||
pll_sleep_en = 1
|
|
||||||
lvds_data_sleep_en = 1
|
|
||||||
lvds_control_sleep_en = 1
|
|
||||||
temp_sense_sleep_en = 1
|
|
||||||
bias_sleep_en = 1
|
|
||||||
self.dac_write(0x23,
|
|
||||||
(dac_sleep_en << 12) | (clkrecv_sleep_en << 11) |
|
|
||||||
(pll_sleep_en << 10) | (lvds_data_sleep_en << 9) |
|
|
||||||
(lvds_control_sleep_en << 8) | (temp_sense_sleep_en << 7) |
|
|
||||||
(1 << 6) | (bias_sleep_en << 5) | (0x1f << 0))
|
|
||||||
# self.dac_write(0x24, 0x0000) # clk and data delays (tuned above)
|
|
||||||
ostrtodig_sel = 0
|
|
||||||
ramp_ena = 0
|
|
||||||
sifdac_ena = 0
|
|
||||||
self.dac_write(0x2d,
|
|
||||||
(ostrtodig_sel << 14) | (ramp_ena << 13) | (0x002 << 1) |
|
|
||||||
(sifdac_ena << 0))
|
|
||||||
grp_delaya = 0x00
|
|
||||||
grp_delayb = 0x00
|
|
||||||
self.dac_write(0x2e, (grp_delaya << 8) | (grp_delayb << 0))
|
|
||||||
grp_delayc = 0x00
|
|
||||||
grp_delayd = 0x00
|
|
||||||
self.dac_write(0x2f, (grp_delayc << 8) | (grp_delayd << 0))
|
|
||||||
sifdac = 0
|
|
||||||
self.dac_write(0x30, sifdac)
|
|
||||||
|
|
||||||
|
delay(10*ms) # let it settle
|
||||||
lvolt = self.dac_read(0x18) & 7
|
lvolt = self.dac_read(0x18) & 7
|
||||||
delay(.1*ms)
|
delay(.1*ms)
|
||||||
if lvolt < 2 or lvolt > 5:
|
if lvolt < 2 or lvolt > 5:
|
||||||
raise ValueError("DAC PLL tuning voltage out of bounds")
|
raise ValueError("DAC PLL tuning voltage out of bounds")
|
||||||
|
|
||||||
|
# self.dac_write(0x20, 0x0000) # stop fifo sync
|
||||||
|
# alarm = self.get_sta() & 1
|
||||||
|
# delay(.1*ms)
|
||||||
|
self.clear_dac_alarms()
|
||||||
|
delay(2*ms) # let it run a bit
|
||||||
|
self.check_dac_alarms()
|
||||||
|
|
||||||
for ch in range(2):
|
for ch in range(2):
|
||||||
channel = self.channel[ch]
|
channel = self.channel[ch]
|
||||||
# test attenuator write and readback
|
# test attenuator write and readback
|
||||||
|
@ -400,7 +253,7 @@ class Phaser:
|
||||||
asf = 0x7fff
|
asf = 0x7fff
|
||||||
# 6pi/4 phase
|
# 6pi/4 phase
|
||||||
oscillator.set_amplitude_phase_mu(asf=asf, pow=0xc000, clr=1)
|
oscillator.set_amplitude_phase_mu(asf=asf, pow=0xc000, clr=1)
|
||||||
delay_mu(8)
|
delay(1*us)
|
||||||
# 3pi/4
|
# 3pi/4
|
||||||
channel.set_duc_phase_mu(0x6000)
|
channel.set_duc_phase_mu(0x6000)
|
||||||
channel.set_duc_cfg(select=0, clr=1)
|
channel.set_duc_cfg(select=0, clr=1)
|
||||||
|
@ -414,19 +267,17 @@ class Phaser:
|
||||||
# allow ripple
|
# allow ripple
|
||||||
if (data_i < sqrt2 - 30 or data_i > sqrt2 or
|
if (data_i < sqrt2 - 30 or data_i > sqrt2 or
|
||||||
abs(data_i - data_q) > 2):
|
abs(data_i - data_q) > 2):
|
||||||
print(data)
|
|
||||||
raise ValueError("DUC+oscillator phase/amplitude test failed")
|
raise ValueError("DUC+oscillator phase/amplitude test failed")
|
||||||
|
|
||||||
# self.dac_write(0x20, 0x0000) # stop fifo sync
|
if has_upconverter:
|
||||||
# alarm = self.get_sta() & 1
|
for data in channel.trf_mmap:
|
||||||
# delay(.1*ms)
|
channel.trf_write(data)
|
||||||
self.clear_dac_alarms()
|
delay(.1*ms)
|
||||||
delay(2*ms) # let it run a bit
|
delay(1*ms) # lock
|
||||||
self.check_dac_alarms()
|
lock_detect = self.get_sta() & (PHASER_STA_TRF0_LD << ch)
|
||||||
|
delay(.1*ms)
|
||||||
hw_rev = self.read8(PHASER_ADDR_HW_REV)
|
if not lock_detect:
|
||||||
has_upconverter = hw_rev & PHASER_HW_REV_VARIANT
|
raise ValueError("TRF quadrature upconverter lock failure")
|
||||||
delay(.1*ms) # slack
|
|
||||||
|
|
||||||
self.set_cfg(clk_sel=clk_sel) # txena
|
self.set_cfg(clk_sel=clk_sel) # txena
|
||||||
|
|
||||||
|
@ -662,7 +513,6 @@ class Phaser:
|
||||||
alarm = self.get_dac_alarms()
|
alarm = self.get_dac_alarms()
|
||||||
delay(.1*ms) # slack
|
delay(.1*ms) # slack
|
||||||
if alarm & ~0x0040: # ignore PLL alarms (see DS)
|
if alarm & ~0x0040: # ignore PLL alarms (see DS)
|
||||||
print(alarm)
|
|
||||||
raise ValueError("DAC alarm")
|
raise ValueError("DAC alarm")
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
|
@ -693,7 +543,9 @@ class Phaser:
|
||||||
if channel.get_dac_data() != data:
|
if channel.get_dac_data() != data:
|
||||||
raise ValueError("DAC test data readback failed")
|
raise ValueError("DAC test data readback failed")
|
||||||
delay(.1*ms)
|
delay(.1*ms)
|
||||||
self.dac_write(0x01, 0x8000) # iotest_ena
|
cfg = self.dac_read(0x01)
|
||||||
|
delay(.1*ms)
|
||||||
|
self.dac_write(0x01, cfg | 0x8000) # iotest_ena
|
||||||
self.dac_write(0x04, 0x0000) # clear iotest_result
|
self.dac_write(0x04, 0x0000) # clear iotest_result
|
||||||
delay(.2*ms) # let it rip
|
delay(.2*ms) # let it rip
|
||||||
# no need to go through the alarm register,
|
# no need to go through the alarm register,
|
||||||
|
@ -706,7 +558,7 @@ class Phaser:
|
||||||
delay(.1*ms) # slack
|
delay(.1*ms) # slack
|
||||||
else:
|
else:
|
||||||
errors = 0
|
errors = 0
|
||||||
self.dac_write(0x01, 0x0000) # clear config
|
self.dac_write(0x01, cfg) # clear config
|
||||||
self.dac_write(0x04, 0x0000) # clear iotest_result
|
self.dac_write(0x04, 0x0000) # clear iotest_result
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
@ -741,11 +593,12 @@ class PhaserChannel:
|
||||||
or overflow after the interpolation. Either band-limit any changes
|
or overflow after the interpolation. Either band-limit any changes
|
||||||
in the oscillator parameters or back off the amplitude sufficiently.
|
in the oscillator parameters or back off the amplitude sufficiently.
|
||||||
"""
|
"""
|
||||||
kernel_invariants = {"index", "phaser"}
|
kernel_invariants = {"index", "phaser", "trf_mmap"}
|
||||||
|
|
||||||
def __init__(self, phaser, index):
|
def __init__(self, phaser, index, trf):
|
||||||
self.phaser = phaser
|
self.phaser = phaser
|
||||||
self.index = index
|
self.index = index
|
||||||
|
self.trf_mmap = TRF372017(trf).get_mmap()
|
||||||
self.oscillator = [PhaserOscillator(self, osc) for osc in range(5)]
|
self.oscillator = [PhaserOscillator(self, osc) for osc in range(5)]
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
class TRF372017:
|
||||||
|
"""TRF372017 settings and register map.
|
||||||
|
|
||||||
|
For possible values, documentation, and explanation, see the datasheet.
|
||||||
|
https://www.ti.com/lit/gpn/trf372017
|
||||||
|
"""
|
||||||
|
rdiv = 21 # 13b
|
||||||
|
ref_inv = 0
|
||||||
|
neg_vco = 1
|
||||||
|
icp = 0 # 1.94 mA, 5b
|
||||||
|
icp_double = 0
|
||||||
|
cal_clk_sel = 12 # /16, 4b
|
||||||
|
|
||||||
|
ndiv = 420 # 16b
|
||||||
|
pll_div_sel = 0b01 # /1, 2b
|
||||||
|
prsc_sel = 1 # 8/9
|
||||||
|
vco_sel = 2 # 2b
|
||||||
|
vcosel_mode = 0
|
||||||
|
cal_acc = 0b00 # 2b
|
||||||
|
en_cal = 1
|
||||||
|
|
||||||
|
nfrac = 0 # 25b
|
||||||
|
|
||||||
|
pwd_pll = 0
|
||||||
|
pwd_cp = 0
|
||||||
|
pwd_vco = 0
|
||||||
|
pwd_vcomux = 0
|
||||||
|
pwd_div124 = 0
|
||||||
|
pwd_presc = 0
|
||||||
|
pwd_out_buff = 1
|
||||||
|
pwd_lo_div = 1
|
||||||
|
pwd_tx_div = 0
|
||||||
|
pwd_bb_vcm = 0
|
||||||
|
pwd_dc_off = 0
|
||||||
|
en_extvco = 0
|
||||||
|
en_isource = 0
|
||||||
|
ld_ana_prec = 0 # 2b
|
||||||
|
cp_tristate = 0 # 2b
|
||||||
|
speedup = 0
|
||||||
|
ld_dig_prec = 0
|
||||||
|
en_dith = 1
|
||||||
|
mod_ord = 2 # 3rd order, 2b
|
||||||
|
dith_sel = 0
|
||||||
|
del_sd_clk = 2 # 2b
|
||||||
|
en_frac = 0
|
||||||
|
|
||||||
|
vcobias_rtrim = 4 # 3b
|
||||||
|
pllbias_rtrim = 2 # 2b
|
||||||
|
vco_bias = 8 # 460 µA, 4b
|
||||||
|
vcobuf_bias = 2 # 2b
|
||||||
|
vcomux_bias = 3 # 2b
|
||||||
|
bufout_bias = 0 # 300 µA, 2b
|
||||||
|
vco_cal_ib = 0 # PTAT
|
||||||
|
vco_cal_ref = 2 # 1.04 V, 2b
|
||||||
|
vco_ampl_ctrl = 3 # 2b
|
||||||
|
vco_vb_ctrl = 0 # 1.2 V, 2b
|
||||||
|
en_ld_isource = 0
|
||||||
|
|
||||||
|
ioff = 0x80 # 8b
|
||||||
|
qoff = 0x80 # 8b
|
||||||
|
vref_sel = 4 # 0.85 V, 3b
|
||||||
|
tx_div_sel = 1 # div2, 2b
|
||||||
|
lo_div_sel = 3 # div8, 2b
|
||||||
|
tx_div_bias = 1 # 37.5 µA, 2b
|
||||||
|
lo_div_bias = 2 # 50 µA, 2b
|
||||||
|
|
||||||
|
vco_trim = 0x20 # 6b
|
||||||
|
vco_test_mode = 0
|
||||||
|
cal_bypass = 0
|
||||||
|
mux_ctrl = 1 # lock detect, 3b
|
||||||
|
isource_sink = 0
|
||||||
|
isource_trim = 4 # 3b
|
||||||
|
pd_tc = 0 # 2b
|
||||||
|
ib_vcm_sel = 0 # ptat
|
||||||
|
dcoffset_i = 2 # 150 µA, 2b
|
||||||
|
vco_bias_sel = 1 # spi
|
||||||
|
|
||||||
|
def __init__(self, updates=None):
|
||||||
|
if updates is None:
|
||||||
|
return
|
||||||
|
for key, value in updates.items():
|
||||||
|
if not hasattr(self, key):
|
||||||
|
raise KeyError("invalid setting", key)
|
||||||
|
setattr(self, key, value)
|
||||||
|
|
||||||
|
def get_mmap(self):
|
||||||
|
mmap = []
|
||||||
|
mmap.append(
|
||||||
|
0x9 |
|
||||||
|
(self.rdiv << 5) | (self.ref_inv << 19) | (self.neg_vco << 20) |
|
||||||
|
(self.icp << 21) | (self.icp_double << 26) |
|
||||||
|
(self.cal_clk_sel << 27))
|
||||||
|
mmap.append(
|
||||||
|
0xa |
|
||||||
|
(self.ndiv << 5) | (self.pll_div_sel << 21) | (self.prsc_sel << 23) |
|
||||||
|
(self.vco_sel << 26) | (self.vcosel_mode << 28) |
|
||||||
|
(self.cal_acc << 29) | (self.en_cal << 31))
|
||||||
|
mmap.append(0xb | (self.nfrac << 5))
|
||||||
|
mmap.append(
|
||||||
|
0xc |
|
||||||
|
(self.pwd_pll << 5) | (self.pwd_cp << 6) | (self.pwd_vco << 7) |
|
||||||
|
(self.pwd_vcomux << 8) | (self.pwd_div124 << 9) |
|
||||||
|
(self.pwd_presc << 10) | (self.pwd_out_buff << 12) |
|
||||||
|
(self.pwd_lo_div << 13) | (self.pwd_tx_div << 14) |
|
||||||
|
(self.pwd_bb_vcm << 15) | (self.pwd_dc_off << 16) |
|
||||||
|
(self.en_extvco << 17) | (self.en_isource << 18) |
|
||||||
|
(self.ld_ana_prec << 19) | (self.cp_tristate << 21) |
|
||||||
|
(self.speedup << 23) | (self.ld_dig_prec << 24) |
|
||||||
|
(self.en_dith << 25) | (self.mod_ord << 27) |
|
||||||
|
(self.dith_sel << 28) | (self.del_sd_clk << 29) |
|
||||||
|
(self.en_frac << 31))
|
||||||
|
mmap.append(
|
||||||
|
0xd |
|
||||||
|
(self.vcobias_rtrim << 5) | (self.pllbias_rtrim << 8) |
|
||||||
|
(self.vco_bias << 10) | (self.vcobuf_bias << 14) |
|
||||||
|
(self.vcomux_bias << 16) | (self.bufout_bias << 18) |
|
||||||
|
(1 << 21) | (self.vco_cal_ib << 22) | (self.vco_cal_ref << 23) |
|
||||||
|
(self.vco_ampl_ctrl << 26) | (self.vco_vb_ctrl << 28) |
|
||||||
|
(self.en_ld_isource << 31))
|
||||||
|
mmap.append(
|
||||||
|
0xe |
|
||||||
|
(self.ioff << 5) | (self.qoff << 13) | (self.vref_sel << 21) |
|
||||||
|
(self.tx_div_sel << 24) | (self.lo_div_sel << 26) |
|
||||||
|
(self.tx_div_bias << 28) | (self.lo_div_bias << 30))
|
||||||
|
mmap.append(
|
||||||
|
0xf |
|
||||||
|
(self.vco_trim << 7) | (self.vco_test_mode << 14) |
|
||||||
|
(self.cal_bypass << 15) | (self.mux_ctrl << 16) |
|
||||||
|
(self.isource_sink << 19) | (self.isource_trim << 20) |
|
||||||
|
(self.pd_tc << 23) | (self.ib_vcm_sel << 25) |
|
||||||
|
(1 << 28) | (self.dcoffset_i << 29) |
|
||||||
|
(self.vco_bias_sel << 31))
|
||||||
|
return mmap
|
Loading…
Reference in New Issue