From 01f762a8f50dc7ec416117c6b1562413fa44b823 Mon Sep 17 00:00:00 2001 From: Robert Jordens Date: Thu, 26 Apr 2018 07:59:08 +0000 Subject: [PATCH] urukul/ad9910: support blind init urukul: always set io_update attribute to silence compiler warning w.r.t. kernel_invariants --- artiq/coredevice/ad9910.py | 21 ++++++++++++++------- artiq/coredevice/urukul.py | 27 ++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/artiq/coredevice/ad9910.py b/artiq/coredevice/ad9910.py index 4be5d8ff7..6ef26a405 100644 --- a/artiq/coredevice/ad9910.py +++ b/artiq/coredevice/ad9910.py @@ -57,7 +57,7 @@ class AD9910: self.cpld = dmgr.get(cpld_device) self.core = self.cpld.core self.bus = self.cpld.bus - assert 4 <= chip_select <= 7 + assert 3 <= chip_select <= 7 self.chip_select = chip_select if sw_device: self.sw = dmgr.get(sw_device) @@ -124,21 +124,25 @@ class AD9910: self.bus.write(data_low) @kernel - def init(self): + def init(self, blind=False): """Initialize and configure the DDS. Sets up SPI mode, confirms chip presence, powers down unused blocks, configures the PLL, waits for PLL lock. Uses the IO_UPDATE signal multiple times. + + :param blind: Do not read back DDS identity and do not wait for lock. """ # Set SPI mode self.write32(_AD9910_REG_CFR1, 0x00000002) self.cpld.io_update.pulse(2*us) - # Use the AUX DAC setting to identify and confirm presence - aux_dac = self.read32(_AD9910_REG_AUX_DAC) - if aux_dac & 0xff != 0x7f: - raise ValueError("Urukul AD9910 AUX_DAC mismatch") - delay(50*us) # slack + delay(1*ms) + if not blind: + # Use the AUX DAC setting to identify and confirm presence + aux_dac = self.read32(_AD9910_REG_AUX_DAC) + if aux_dac & 0xff != 0x7f: + raise ValueError("Urukul AD9910 AUX_DAC mismatch") + delay(50*us) # slack # Configure PLL settings and bring up PLL self.write32(_AD9910_REG_CFR2, 0x01400020) self.cpld.io_update.pulse(2*us) @@ -148,6 +152,9 @@ class AD9910: self.cpld.io_update.pulse(100*us) self.write32(_AD9910_REG_CFR3, cfr3) self.cpld.io_update.pulse(100*us) + if blind: + delay(100*ms) + return # Wait for PLL lock, up to 100 ms for i in range(100): sta = self.cpld.sta_read() diff --git a/artiq/coredevice/urukul.py b/artiq/coredevice/urukul.py index 76782f706..a2ce2365f 100644 --- a/artiq/coredevice/urukul.py +++ b/artiq/coredevice/urukul.py @@ -95,6 +95,18 @@ def urukul_sta_proto_rev(sta): 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: """Urukul CPLD SPI router and configuration interface. @@ -122,6 +134,8 @@ class CPLD: self.bus = dmgr.get(spi_device) if io_update_device is not None: self.io_update = dmgr.get(io_update_device) + else: + self.io_update = _RegIOUpdate(self) if dds_reset_device is not None: self.dds_reset = dmgr.get(dds_reset_device) @@ -164,20 +178,23 @@ class CPLD: return self.bus.read() @kernel - def init(self): + def init(self, blind=False): """Initialize and detect Urukul. Resets the DDS I/O interface and verifies correct CPLD gateware version. 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 # Don't pulse MASTER_RESET (m-labs/artiq#940) self.cfg_reg = cfg | (0 << CFG_RST) | (1 << CFG_IO_RST) - proto_rev = urukul_sta_proto_rev(self.sta_read()) - if proto_rev != STA_PROTO_REV_MATCH: - raise ValueError("Urukul proto_rev mismatch") - delay(20*us) # slack, reset + if not blind: + proto_rev = urukul_sta_proto_rev(self.sta_read()) + if proto_rev != STA_PROTO_REV_MATCH: + raise ValueError("Urukul proto_rev mismatch") + delay(100*us) # reset, slack self.cfg_write(cfg) delay(1*ms) # DDS wake up