forked from M-Labs/artiq
1
0
Fork 0

fastino: robustify init()

* init() now also clear and resets more state including the interpolators.
  If not done, this PLL unlocks/locks may lead to random interpolator state
  on boot to which the CICs react badly.
* Use and expose `t_frame`
* Clarify implementation state of `read()`
This commit is contained in:
Robert Jördens 2022-02-16 14:34:22 +00:00
parent 65eab31f23
commit 08b65470cd
1 changed files with 31 additions and 9 deletions

View File

@ -1,12 +1,12 @@
"""RTIO driver for the Fastino 32channel, 16 bit, 2.5 MS/s per channel, """RTIO driver for the Fastino 32channel, 16 bit, 2.5 MS/s per channel,
streaming DAC. streaming DAC.
""" """
from numpy import int32 from numpy import int32, int64
from artiq.language.core import kernel, portable, delay, delay_mu from artiq.language.core import kernel, portable, delay, delay_mu
from artiq.coredevice.rtio import (rtio_output, rtio_output_wide, from artiq.coredevice.rtio import (rtio_output, rtio_output_wide,
rtio_input_data) rtio_input_data)
from artiq.language.units import us from artiq.language.units import ns
from artiq.language.types import TInt32, TList from artiq.language.types import TInt32, TList
@ -41,24 +41,45 @@ class Fastino:
:param log2_width: Width of DAC channel group (logarithm base 2). :param log2_width: Width of DAC channel group (logarithm base 2).
Value must match the corresponding value in the RTIO PHY (gateware). Value must match the corresponding value in the RTIO PHY (gateware).
""" """
kernel_invariants = {"core", "channel", "width"} kernel_invariants = {"core", "channel", "width", "t_frame"}
def __init__(self, dmgr, channel, core_device="core", log2_width=0): def __init__(self, dmgr, channel, core_device="core", log2_width=0):
self.channel = channel << 8 self.channel = channel << 8
self.core = dmgr.get(core_device) self.core = dmgr.get(core_device)
self.width = 1 << log2_width self.width = 1 << log2_width
# frame duration in mu (14 words each 7 clock cycles each 4 ns)
# self.core.seconds_to_mu(14*7*4*ns) # unfortunately this may round wrong
assert self.core.ref_period == 1*ns
self.t_frame = int64(14*7*4)
@kernel @kernel
def init(self): def init(self):
"""Initialize the device. """Initialize the device.
This clears reset, unsets DAC_CLR, enables AFE_PWR, * disables RESET, DAC_CLR, enables AFE_PWR
clears error counters, then enables error counting * clears error counters, enables error counting
* turns LEDs off
* clears `hold` and `continuous` on all channels
* clear and resets interpolators to unit rate change on all
channels
It does not change set channel voltages and does not reset the PLLs or clock
domains.
""" """
self.set_cfg(reset=0, afe_power_down=0, dac_clr=0, clr_err=1) self.set_cfg(reset=0, afe_power_down=0, dac_clr=0, clr_err=1)
delay(1*us) delay_mu(self.t_frame)
self.set_cfg(reset=0, afe_power_down=0, dac_clr=0, clr_err=0) self.set_cfg(reset=0, afe_power_down=0, dac_clr=0, clr_err=0)
delay(1*us) delay_mu(self.t_frame)
self.set_continuous(0)
delay_mu(self.t_frame)
self.stage_cic(1)
delay_mu(self.t_frame)
self.apply_cic(0xffffffff)
delay_mu(self.t_frame)
self.set_leds(0)
delay_mu(self.t_frame)
self.set_hold(0)
delay_mu(self.t_frame)
@kernel @kernel
def write(self, addr, data): def write(self, addr, data):
@ -78,8 +99,9 @@ class Fastino:
:param addr: Address to read from. :param addr: Address to read from.
:return: The data read. :return: The data read.
""" """
rtio_output(self.channel | addr | 0x80) raise NotImplementedError
return rtio_input_data(self.channel >> 8) # rtio_output(self.channel | addr | 0x80)
# return rtio_input_data(self.channel >> 8)
@kernel @kernel
def set_dac_mu(self, dac, data): def set_dac_mu(self, dac, data):