forked from M-Labs/artiq
1
0
Fork 0

urukul/ad9910: support blind init

urukul: always set io_update attribute
to silence compiler warning w.r.t. kernel_invariants
This commit is contained in:
Robert Jördens 2018-04-26 07:59:08 +00:00 committed by Robert Jordens
parent 3802c7badb
commit 01f762a8f5
2 changed files with 36 additions and 12 deletions

View File

@ -57,7 +57,7 @@ class AD9910:
self.cpld = dmgr.get(cpld_device) self.cpld = dmgr.get(cpld_device)
self.core = self.cpld.core self.core = self.cpld.core
self.bus = self.cpld.bus self.bus = self.cpld.bus
assert 4 <= chip_select <= 7 assert 3 <= chip_select <= 7
self.chip_select = chip_select self.chip_select = chip_select
if sw_device: if sw_device:
self.sw = dmgr.get(sw_device) self.sw = dmgr.get(sw_device)
@ -124,21 +124,25 @@ class AD9910:
self.bus.write(data_low) self.bus.write(data_low)
@kernel @kernel
def init(self): def init(self, blind=False):
"""Initialize and configure the DDS. """Initialize and configure the DDS.
Sets up SPI mode, confirms chip presence, powers down unused blocks, Sets up SPI mode, confirms chip presence, powers down unused blocks,
configures the PLL, waits for PLL lock. Uses the configures the PLL, waits for PLL lock. Uses the
IO_UPDATE signal multiple times. IO_UPDATE signal multiple times.
:param blind: Do not read back DDS identity and do not wait for lock.
""" """
# Set SPI mode # Set SPI mode
self.write32(_AD9910_REG_CFR1, 0x00000002) self.write32(_AD9910_REG_CFR1, 0x00000002)
self.cpld.io_update.pulse(2*us) self.cpld.io_update.pulse(2*us)
# Use the AUX DAC setting to identify and confirm presence delay(1*ms)
aux_dac = self.read32(_AD9910_REG_AUX_DAC) if not blind:
if aux_dac & 0xff != 0x7f: # Use the AUX DAC setting to identify and confirm presence
raise ValueError("Urukul AD9910 AUX_DAC mismatch") aux_dac = self.read32(_AD9910_REG_AUX_DAC)
delay(50*us) # slack if aux_dac & 0xff != 0x7f:
raise ValueError("Urukul AD9910 AUX_DAC mismatch")
delay(50*us) # slack
# Configure PLL settings and bring up PLL # Configure PLL settings and bring up PLL
self.write32(_AD9910_REG_CFR2, 0x01400020) self.write32(_AD9910_REG_CFR2, 0x01400020)
self.cpld.io_update.pulse(2*us) self.cpld.io_update.pulse(2*us)
@ -148,6 +152,9 @@ class AD9910:
self.cpld.io_update.pulse(100*us) self.cpld.io_update.pulse(100*us)
self.write32(_AD9910_REG_CFR3, cfr3) self.write32(_AD9910_REG_CFR3, cfr3)
self.cpld.io_update.pulse(100*us) self.cpld.io_update.pulse(100*us)
if blind:
delay(100*ms)
return
# Wait for PLL lock, up to 100 ms # Wait for PLL lock, up to 100 ms
for i in range(100): for i in range(100):
sta = self.cpld.sta_read() sta = self.cpld.sta_read()

View File

@ -95,6 +95,18 @@ def urukul_sta_proto_rev(sta):
return (sta >> STA_PROTO_REV) & 0x7f return (sta >> STA_PROTO_REV) & 0x7f
class _RegIOUpdate:
def __init__(self, cpld):
self.cpld = cpld
@portable
def pulse(self, t):
cfg = self.cpld.cfg_reg
self.cpld.cfg_write(cfg | (1 << CFG_IO_UPDATE))
delay(t)
self.cpld.cfg_write(cfg)
class CPLD: class CPLD:
"""Urukul CPLD SPI router and configuration interface. """Urukul CPLD SPI router and configuration interface.
@ -122,6 +134,8 @@ class CPLD:
self.bus = dmgr.get(spi_device) self.bus = dmgr.get(spi_device)
if io_update_device is not None: if io_update_device is not None:
self.io_update = dmgr.get(io_update_device) self.io_update = dmgr.get(io_update_device)
else:
self.io_update = _RegIOUpdate(self)
if dds_reset_device is not None: if dds_reset_device is not None:
self.dds_reset = dmgr.get(dds_reset_device) self.dds_reset = dmgr.get(dds_reset_device)
@ -164,20 +178,23 @@ class CPLD:
return self.bus.read() return self.bus.read()
@kernel @kernel
def init(self): def init(self, blind=False):
"""Initialize and detect Urukul. """Initialize and detect Urukul.
Resets the DDS I/O interface and verifies correct CPLD gateware Resets the DDS I/O interface and verifies correct CPLD gateware
version. version.
Does not pulse the DDS MASTER_RESET as that confuses the AD9910. Does not pulse the DDS MASTER_RESET as that confuses the AD9910.
:param blind: Do not attempt to verify presence and compatibility.
""" """
cfg = self.cfg_reg cfg = self.cfg_reg
# Don't pulse MASTER_RESET (m-labs/artiq#940) # Don't pulse MASTER_RESET (m-labs/artiq#940)
self.cfg_reg = cfg | (0 << CFG_RST) | (1 << CFG_IO_RST) self.cfg_reg = cfg | (0 << CFG_RST) | (1 << CFG_IO_RST)
proto_rev = urukul_sta_proto_rev(self.sta_read()) if not blind:
if proto_rev != STA_PROTO_REV_MATCH: proto_rev = urukul_sta_proto_rev(self.sta_read())
raise ValueError("Urukul proto_rev mismatch") if proto_rev != STA_PROTO_REV_MATCH:
delay(20*us) # slack, reset raise ValueError("Urukul proto_rev mismatch")
delay(100*us) # reset, slack
self.cfg_write(cfg) self.cfg_write(cfg)
delay(1*ms) # DDS wake up delay(1*ms) # DDS wake up