forked from M-Labs/artiq
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:
parent
3802c7badb
commit
01f762a8f5
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue