mirror of https://github.com/m-labs/artiq.git
urukul: document ad9912, and cpld, fix api
This commit is contained in:
parent
ede98679fc
commit
2adba3ed33
|
@ -149,7 +149,7 @@ class AD9910:
|
|||
raise ValueError("PLL failed to lock")
|
||||
|
||||
@kernel
|
||||
def set_mu(self, ftw, pow=0, asf=0x3fff):
|
||||
def set_mu(self, ftw=int32(0), pow=int32(0), asf=int32(0x3fff)):
|
||||
"""Set profile 0 data in machine units.
|
||||
|
||||
After the SPI transfer, the shared IO update pin is pulsed to
|
||||
|
@ -195,9 +195,11 @@ class AD9910:
|
|||
self.amplitude_to_asf(amplitude))
|
||||
|
||||
@kernel
|
||||
def set_att_mu(self, att):
|
||||
def set_att_mu(self, att=int32(0)):
|
||||
"""Set digital step attenuator in machine units.
|
||||
|
||||
.. seealso:: :meth:`artiq.coredevice.urukul.CPLD.set_att_mu`
|
||||
|
||||
:param att: Attenuation setting, 8 bit digital.
|
||||
"""
|
||||
self.cpld.set_att_mu(self.chip_select - 4, att)
|
||||
|
@ -206,6 +208,8 @@ class AD9910:
|
|||
def set_att(self, att):
|
||||
"""Set digital step attenuator in SI units.
|
||||
|
||||
.. seealso:: :meth:`artiq.coredevice.urukul.CPLD.set_att`
|
||||
|
||||
:param att: Attenuation in dB.
|
||||
"""
|
||||
self.cpld.set_att(self.chip_select - 4, att)
|
||||
|
|
|
@ -7,11 +7,19 @@ from numpy import int32, int64
|
|||
|
||||
class AD9912:
|
||||
"""
|
||||
Support for the AD9912 DDS on Urukul
|
||||
AD9912 DDS channel on Urukul
|
||||
|
||||
:param chip_select: Chip select configuration.
|
||||
This class supports a single DDS channel and exposes the DDS,
|
||||
the digital step attenuator, and the RF switch.
|
||||
|
||||
:param chip_select: Chip select configuration. On Urukul this is an
|
||||
encoded chip select and not "one-hot".
|
||||
:param cpld_device: Name of the Urukul CPLD this device is on.
|
||||
:param sw_device: Name of the RF switch device.
|
||||
:param sw_device: Name of the RF switch device. The RF switch is a
|
||||
TTLOut channel available as the :attr:`sw` attribute of this instance.
|
||||
:param pll_n: DDS PLL multiplier. The DDS sample clock is
|
||||
f_ref*pll_n where f_ref is the reference frequency (set in the parent
|
||||
Urukul CPLD instance).
|
||||
"""
|
||||
kernel_invariants = {"chip_select", "cpld", "core", "bus", "sw",
|
||||
"ftw_per_hz", "sysclk", "pll_n"}
|
||||
|
@ -27,10 +35,17 @@ class AD9912:
|
|||
self.sw = dmgr.get(sw_device)
|
||||
self.pll_n = pll_n
|
||||
self.sysclk = self.cpld.refclk*pll_n
|
||||
assert self.sysclk < 1e9
|
||||
self.ftw_per_hz = 1/self.sysclk*(int64(1) << 48)
|
||||
|
||||
@kernel
|
||||
def write(self, addr, data, length=1):
|
||||
def write(self, addr=int32(0), data=int32(0), length=int32(1)):
|
||||
"""Variable length write to a register. Up to 32 bits.
|
||||
|
||||
:param addr: Register address
|
||||
:param data: Data to be written: int32
|
||||
:param length: Length in bytes (1-4)
|
||||
"""
|
||||
assert length > 0
|
||||
assert length <= 4
|
||||
self.bus.set_xfer(self.chip_select, 16, 0)
|
||||
|
@ -41,7 +56,12 @@ class AD9912:
|
|||
delay_mu(self.bus.xfer_period_mu - self.bus.write_period_mu)
|
||||
|
||||
@kernel
|
||||
def read(self, addr, length=1):
|
||||
def read(self, addr=int32(0), length=int32(1)):
|
||||
"""Variable length read from a register. Up to 32 bits.
|
||||
|
||||
:param addr: Register address
|
||||
:param length: Length in bytes (1-4)
|
||||
"""
|
||||
assert length > 0
|
||||
assert length <= 4
|
||||
self.bus.set_xfer(self.chip_select, 16, 0)
|
||||
|
@ -57,8 +77,11 @@ class AD9912:
|
|||
|
||||
@kernel
|
||||
def init(self):
|
||||
"""Initialize and configure the DDS."""
|
||||
t = now_mu()
|
||||
# SPI mode
|
||||
self.write(AD9912_SER_CONF, 0x99)
|
||||
# Verify chip ID and presence
|
||||
prodid = self.read(AD9912_PRODIDH, length=2)
|
||||
if (prodid != 0x1982) and (prodid != 0x1902):
|
||||
raise ValueError("Urukul AD9912 product id mismatch")
|
||||
|
@ -69,19 +92,39 @@ class AD9912:
|
|||
delay(10*us)
|
||||
self.write(AD9912_PLLCFG, 0b00000101) # 375 µA, high range
|
||||
at_mu(t)
|
||||
delay(100*us)
|
||||
delay(100*us) # constant duration of 100 µs
|
||||
|
||||
@kernel
|
||||
def set_att_mu(self, att):
|
||||
"""Set digital step attenuator in machine units.
|
||||
|
||||
.. seealso:: :meth:`artiq.coredevice.urukul.CPLD.set_att_mu`
|
||||
|
||||
:param att: Attenuation setting, 8 bit digital.
|
||||
"""
|
||||
self.cpld.set_att_mu(self.chip_select - 4, att)
|
||||
|
||||
@kernel
|
||||
def set_att(self, att):
|
||||
"""Set digital step attenuator in SI units.
|
||||
|
||||
.. seealso:: :meth:`artiq.coredevice.urukul.CPLD.set_att`
|
||||
|
||||
:param att: Attenuation in dB.
|
||||
"""
|
||||
self.cpld.set_att(self.chip_select - 4, att)
|
||||
|
||||
@kernel
|
||||
def set_mu(self, ftw=int64(0), pow=int32(0)):
|
||||
# do a streaming transfer of FTW and POW
|
||||
"""Set profile 0 data in machine units.
|
||||
|
||||
After the SPI transfer, the shared IO update pin is pulsed to
|
||||
activate the data.
|
||||
|
||||
:param ftw: Frequency tuning word: 32 bit unsigned.
|
||||
:param pow: Phase tuning word: 16 bit unsigned.
|
||||
"""
|
||||
# streaming transfer of FTW and POW
|
||||
self.bus.set_xfer(self.chip_select, 16, 0)
|
||||
self.bus.write((AD9912_POW1 << 16) | (3 << 29))
|
||||
delay_mu(-self.bus.xfer_period_mu)
|
||||
|
@ -107,5 +150,12 @@ class AD9912:
|
|||
|
||||
@kernel
|
||||
def set(self, frequency, phase=0.0):
|
||||
"""Set profile 0 data in SI units.
|
||||
|
||||
.. seealso:: :meth:`set_mu`
|
||||
|
||||
:param ftw: Frequency in Hz
|
||||
:param pow: Phase tuning word in turns
|
||||
"""
|
||||
self.set_mu(self.frequency_to_ftw(frequency),
|
||||
self.turns_to_pow(phase))
|
||||
|
|
|
@ -87,6 +87,15 @@ CS_DDS_CH3 = 7
|
|||
|
||||
|
||||
class CPLD:
|
||||
"""Urukul CPLD SPI router and configuration interface.
|
||||
|
||||
:param spi_device: SPI bus device name
|
||||
:param io_update_device: IO update RTIO TTLOut channel name
|
||||
:param dds_reset_device: DDS reset RTIO TTLOut channel name
|
||||
:param refclk: Reference clock (SMA, MMCX or on-board 100 MHz oscillator)
|
||||
frequency in Hz
|
||||
:param core_device: Core device name
|
||||
"""
|
||||
def __init__(self, dmgr, spi_device, io_update_device,
|
||||
dds_reset_device=None,
|
||||
refclk=100e6, core_device="core"):
|
||||
|
@ -103,12 +112,17 @@ class CPLD:
|
|||
self.att_reg = int32(0)
|
||||
|
||||
@kernel
|
||||
def cfg_write(self, cfg_reg):
|
||||
def cfg_write(self, data=int32(0)):
|
||||
"""Write to the configuration register.
|
||||
|
||||
:param data: 24 bit data to be written. Will be stored at
|
||||
:attr:`cfg_reg`.
|
||||
"""
|
||||
self.bus.set_config_mu(_SPI_CONFIG, _SPIT_CFG_WR, _SPIT_CFG_RD)
|
||||
self.bus.set_xfer(CS_CFG, 24, 0)
|
||||
self.bus.write(cfg_reg << 8)
|
||||
self.bus.write(data << 8)
|
||||
self.bus.set_config_mu(_SPI_CONFIG, _SPIT_DDS_WR, _SPIT_DDS_RD)
|
||||
self.cfg_reg = cfg_reg
|
||||
self.cfg_reg = data
|
||||
|
||||
@kernel
|
||||
def sta_read(self):
|
||||
|
@ -150,11 +164,12 @@ class CPLD:
|
|||
self.cfg_write(c)
|
||||
|
||||
@kernel
|
||||
def set_att_mu(self, channel, att):
|
||||
"""
|
||||
Parameters:
|
||||
att (int): 0-255, 255 minimum attenuation,
|
||||
0 maximum attenuation (31.5 dB)
|
||||
def set_att_mu(self, channel=int32(0), att=int32(0)):
|
||||
"""Set digital step attenuator in machine units.
|
||||
|
||||
:param channel: Attenuator channel (0-3).
|
||||
:param att: Digital attenuation setting:
|
||||
255 minimum attenuation, 0 maximum attenuation (31.5 dB)
|
||||
"""
|
||||
a = self.att_reg & ~(0xff << (channel * 8))
|
||||
a |= att << (channel * 8)
|
||||
|
@ -165,4 +180,9 @@ class CPLD:
|
|||
|
||||
@kernel
|
||||
def set_att(self, channel, att):
|
||||
"""Set digital step attenuator in SI units.
|
||||
|
||||
:param channel: Attenuator channel (0-3).
|
||||
:param att: Attenuation in dB.
|
||||
"""
|
||||
self.set_att_mu(channel, 255 - int32(round(att*8)))
|
||||
|
|
|
@ -68,3 +68,21 @@ These drivers are for the core device and the peripherals closely integrated int
|
|||
|
||||
.. automodule:: artiq.coredevice.sawg
|
||||
:members:
|
||||
|
||||
:mod:`artiq.coredevice.urukul` module
|
||||
-------------------------------------
|
||||
|
||||
.. automodule:: artiq.coredevice.urukul
|
||||
:members:
|
||||
|
||||
:mod:`artiq.coredevice.ad9912` module
|
||||
-------------------------------------
|
||||
|
||||
.. automodule:: artiq.coredevice.ad9912
|
||||
:members:
|
||||
|
||||
:mod:`artiq.coredevice.ad9910` module
|
||||
-------------------------------------
|
||||
|
||||
.. automodule:: artiq.coredevice.ad9910
|
||||
:members:
|
||||
|
|
Loading…
Reference in New Issue