forked from M-Labs/artiq
ad9910: support reading synchronization values from EEPROM
This commit is contained in:
parent
852048dce4
commit
04e0c23e78
|
@ -1,4 +1,5 @@
|
||||||
from numpy import int32, int64
|
from numpy import int32, int64
|
||||||
|
import functools
|
||||||
|
|
||||||
from artiq.language.core import (
|
from artiq.language.core import (
|
||||||
kernel, delay, portable, delay_mu, now_mu, at_mu)
|
kernel, delay, portable, delay_mu, now_mu, at_mu)
|
||||||
|
@ -86,9 +87,13 @@ class AD9910:
|
||||||
To stabilize the SYNC_IN delay tuning, run :meth:`tune_sync_delay` once
|
To stabilize the SYNC_IN delay tuning, run :meth:`tune_sync_delay` once
|
||||||
and set this to the delay tap number returned (default: -1 to signal no
|
and set this to the delay tap number returned (default: -1 to signal no
|
||||||
synchronization and no tuning during :meth:`init`).
|
synchronization and no tuning during :meth:`init`).
|
||||||
|
Can be a string of the form "eeprom_device:byte_offset" to read the value
|
||||||
|
from a I2C EEPROM.
|
||||||
:param io_update_delay: IO_UPDATE pulse alignment delay.
|
:param io_update_delay: IO_UPDATE pulse alignment delay.
|
||||||
To align IO_UPDATE to SYNC_CLK, run :meth:`tune_io_update_delay` and
|
To align IO_UPDATE to SYNC_CLK, run :meth:`tune_io_update_delay` and
|
||||||
set this to the delay tap number returned.
|
set this to the delay tap number returned.
|
||||||
|
Can be a string of the form "eeprom_device:byte_offset" to read the value
|
||||||
|
from a I2C EEPROM.
|
||||||
"""
|
"""
|
||||||
kernel_invariants = {"chip_select", "cpld", "core", "bus",
|
kernel_invariants = {"chip_select", "cpld", "core", "bus",
|
||||||
"ftw_per_hz", "io_update_delay", "sysclk_per_mu"}
|
"ftw_per_hz", "io_update_delay", "sysclk_per_mu"}
|
||||||
|
@ -123,12 +128,39 @@ class AD9910:
|
||||||
assert sysclk <= 1e9
|
assert sysclk <= 1e9
|
||||||
self.ftw_per_hz = (1 << 32)/sysclk
|
self.ftw_per_hz = (1 << 32)/sysclk
|
||||||
self.sysclk_per_mu = int(round(sysclk*self.core.ref_period))
|
self.sysclk_per_mu = int(round(sysclk*self.core.ref_period))
|
||||||
|
|
||||||
|
@functools.lru_cache(maxsize=2)
|
||||||
|
def get_eeprom_sync_data(eeprom_str):
|
||||||
|
device, offset = eeprom_str.split(":")
|
||||||
|
device = dmgr.get(device)
|
||||||
|
offset = int(offset)
|
||||||
|
|
||||||
|
word = device.read_i32(offset) >> 16
|
||||||
|
sync_delay_seed = word >> 8
|
||||||
|
if sync_delay_seed >= 0:
|
||||||
|
io_update_delay = word & 0xff
|
||||||
|
else:
|
||||||
|
io_update_delay = 0
|
||||||
|
return device, offset, sync_delay_seed, io_update_delay
|
||||||
|
|
||||||
|
if isinstance(sync_delay_seed, str):
|
||||||
|
self.sync_delay_seed_eeprom, self.sync_delay_seed_offset, sync_delay_seed, _ = \
|
||||||
|
get_eeprom_sync_data(sync_delay_seed)
|
||||||
|
else:
|
||||||
|
self.sync_delay_seed_eeprom, self.sync_delay_seed_offset = None, None
|
||||||
|
if isinstance(io_update_delay, str):
|
||||||
|
self.io_update_delay_eeprom, self.io_update_delay_offset, _, io_update_delay = \
|
||||||
|
get_eeprom_sync_data(io_update_delay)
|
||||||
|
else:
|
||||||
|
self.io_update_delay_eeprom, self.io_update_delay_offset = None, None
|
||||||
|
|
||||||
if sync_delay_seed >= 0 and not self.cpld.sync_div:
|
if sync_delay_seed >= 0 and not self.cpld.sync_div:
|
||||||
raise ValueError("parent cpld does not drive SYNC")
|
raise ValueError("parent cpld does not drive SYNC")
|
||||||
self.sync_delay_seed = sync_delay_seed
|
self.sync_delay_seed = sync_delay_seed
|
||||||
if self.sync_delay_seed >= 0:
|
if self.sync_delay_seed >= 0:
|
||||||
assert self.sysclk_per_mu == sysclk*self.core.ref_period
|
assert self.sysclk_per_mu == sysclk*self.core.ref_period
|
||||||
self.io_update_delay = io_update_delay
|
self.io_update_delay = io_update_delay
|
||||||
|
|
||||||
self.phase_mode = PHASE_MODE_CONTINUOUS
|
self.phase_mode = PHASE_MODE_CONTINUOUS
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
|
|
Loading…
Reference in New Issue