forked from M-Labs/artiq
Merge branch 'phaser2-rust-init'
This commit is contained in:
commit
fbf5a4d4a2
@ -1,7 +1,7 @@
|
||||
ARTIQ Phaser
|
||||
============
|
||||
|
||||
This ARTIQ branch contains a proof-of-concept design of a GHz-datarate, multi-channel, interpolating, multi-tone, direct digital synthesizer (DDS) compatible with ARTIQ's RTIO channels.
|
||||
ARTIQ contains a proof-of-concept design of a GHz-datarate, multi-channel, interpolating, multi-tone, direct digital synthesizer (DDS) compatible with ARTIQ's RTIO channels.
|
||||
Ultimately it will be the basis for the ARTIQ Sayma Smart Arbitrary Waveform Generator project. See https://github.com/m-labs/sinara and https://github.com/m-labs/artiq-hardware.
|
||||
|
||||
*Features*:
|
||||
@ -15,13 +15,13 @@ Ultimately it will be the basis for the ARTIQ Sayma Smart Arbitrary Waveform Gen
|
||||
* Parametrized JESD204B core (also capable of operation with eight lanes)
|
||||
* The code can be reconfigured. Possible example configurations are: support 2 channels at 1 GHz datarate, support 4 channels at 300 MHz data rate, no interpolation, and using mix mode to stress the second and third Nyquist zones (150-300 MHz and 300-450 MHz).
|
||||
|
||||
The hardware required to use the ARTIQ phaser branch is a KC705 with an AD9154-FMC-EBZ plugged into the HPC connector and a low-noise sample rate reference clock.
|
||||
The hardware required is a KC705 with an AD9154-FMC-EBZ plugged into the HPC connector and a low-noise sample rate reference clock.
|
||||
|
||||
This work was supported by the Army Research Lab and the University of Maryland.
|
||||
|
||||
The code that was developed for this project is located in several repositories:
|
||||
|
||||
* In ARTIQ, the SAWG and Phaser code: https://github.com/m-labs/artiq/compare/phaser2
|
||||
* In ARTIQ, the SAWG and Phaser code: https://github.com/m-labs/artiq
|
||||
* The Migen/MiSoC JESD204B core: https://github.com/m-labs/jesd204b
|
||||
|
||||
|
||||
@ -49,11 +49,11 @@ https://m-labs.hk/artiq/manual-master/index.html
|
||||
- binutils-or1k-linux
|
||||
|
||||
* Install a recent version of Vivado (tested and developed with 2016.2).
|
||||
* Do a checkout of the ARTIQ phaser2 branch: ::
|
||||
* Do a checkout of ARTIQ: ::
|
||||
|
||||
mkdir ~/src
|
||||
cd ~/src
|
||||
git clone --recursive -b phaser2 https://github.com/m-labs/artiq.git
|
||||
git clone --recursive https://github.com/m-labs/artiq.git
|
||||
cd ../artiq
|
||||
python setup.py develop
|
||||
|
||||
@ -89,29 +89,19 @@ Setup
|
||||
* Refer to the ARTIQ documentation to configure an IP address and other settings for the transmitter device.
|
||||
If the board was running stock ARTIQ before, the settings will be kept.
|
||||
* A 300 MHz clock of roughly 10 dBm (0.2 to 3.4 V peak-to-peak into 50 Ohm) must be connected to the AD9154-FMC-EBZ J1.
|
||||
The external RTIO clock, DAC deviceclock, FPGA deviceclock, and SYSREF are derived from this signal. There is no internal RTIO clock.
|
||||
The RTIO clock, DAC deviceclock, FPGA deviceclock, and SYSREF are derived from this signal.
|
||||
* An example device database, several status and test scripts are provided in ``artiq/examples/phaser/``. ::
|
||||
|
||||
cd artiq/examples/phaser
|
||||
|
||||
* Edit ``device_db.pyon`` to match the hostname or IP address of the core device.
|
||||
* The ``startup_clock`` needs to be set to internal (``i``) for bootstrapping the clock distribution tree.
|
||||
* Compile and flash the startup kernel in ``artiq/examples/phaser/startup_kernel.py``.
|
||||
* Erase any possible idle kernels.
|
||||
* Use ``ping`` and ``flterm`` to verify that the core device starts up and boots correctly.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
* After each boot, run the ``dac_setup.py`` experiment to establish the JESD204B links (``artiq_run repository/dac_setup.py``).
|
||||
* Run ``artiq_run repository/ad9154_test_status.py`` to retrieve and print several status registers from the AD9154 DAC.
|
||||
* Run ``artiq_run repository/ad9154_test_prbs.py`` to test the JESD204B PHY layer for bit errors. Reboot the core device afterwards.
|
||||
* Run ``artiq_run repository/ad9154_test_stpl.py`` to executes a JESD204B short transport layer test.
|
||||
* Run ``artiq_run repository/demo.py`` for an example that exercises several different use cases of synchronized phase, amplitude, and frequency updates.
|
||||
for an example that exercises several different use cases of synchronized phase, amplitude, and frequency updates.
|
||||
* Run ``artiq_run repository/demo_2tone.py`` for an example that emits a shaped two-tone pulse.
|
||||
* Implement your own experiments using the SAWG channels.
|
||||
* Verify clock stability between the sample rate reference clock and the DAC outputs.
|
||||
* Changes to the AD9154 configuration can also be performed at runtime in experiments.
|
||||
See the example ``dac_setup.py``.
|
||||
This can e.g. be used to enable and evaluate mix mode without having to change any other code (bitstream/bios/runtime/startup_kernel).
|
||||
|
@ -1,106 +0,0 @@
|
||||
from artiq.language.core import kernel, syscall
|
||||
from artiq.language.types import TInt32, TNone
|
||||
|
||||
|
||||
@syscall(flags={"nounwind", "nowrite"})
|
||||
def ad9154_init() -> TNone:
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
|
||||
|
||||
@syscall(flags={"nounwind", "nowrite"})
|
||||
def ad9154_write(addr: TInt32, data: TInt32) -> TNone:
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
|
||||
|
||||
@syscall(flags={"nounwind", "nowrite"})
|
||||
def ad9154_read(addr: TInt32) -> TInt32:
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
|
||||
|
||||
@syscall(flags={"nounwind", "nowrite"})
|
||||
def ad9516_write(addr: TInt32, data: TInt32) -> TNone:
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
|
||||
|
||||
@syscall(flags={"nounwind", "nowrite"})
|
||||
def ad9516_read(addr: TInt32) -> TInt32:
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
|
||||
|
||||
@syscall(flags={"nounwind", "nowrite"})
|
||||
def ad9154_jesd_enable(en: TInt32) -> TNone:
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
|
||||
|
||||
@syscall(flags={"nounwind", "nowrite"})
|
||||
def ad9154_jesd_ready() -> TInt32:
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
|
||||
|
||||
@syscall(flags={"nounwind", "nowrite"})
|
||||
def ad9154_jesd_prbs(prbs: TInt32) -> TNone:
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
|
||||
|
||||
@syscall(flags={"nounwind", "nowrite"})
|
||||
def ad9154_jesd_stpl(prbs: TInt32) -> TNone:
|
||||
raise NotImplementedError("syscall not simulated")
|
||||
|
||||
|
||||
class AD9154:
|
||||
"""AD9154-FMC-EBZ SPI support
|
||||
|
||||
There are two devices on the SPI bus, a AD9154 DAC and a AD9516 clock
|
||||
divider/fanout.
|
||||
|
||||
Register and bit names are in :mod:`artiq.coredevice.ad9154_reg` and
|
||||
:mod:`artiq.coredevice.ad9516_reg` respectively.
|
||||
|
||||
The SPI bus does not operate over RTIO but directly. This class does not
|
||||
interact with the timeline.
|
||||
"""
|
||||
def __init__(self, dmgr, core_device="core"):
|
||||
self.core = dmgr.get(core_device)
|
||||
|
||||
@kernel
|
||||
def init(self):
|
||||
"""Initialize and configure the SPI bus."""
|
||||
ad9154_init()
|
||||
|
||||
@kernel
|
||||
def dac_write(self, addr, data):
|
||||
"""Write `data` to AD9154 SPI register at `addr`."""
|
||||
ad9154_write(addr, data)
|
||||
|
||||
@kernel
|
||||
def dac_read(self, addr):
|
||||
"""Read AD9154 SPI register at `addr`."""
|
||||
return ad9154_read(addr)
|
||||
|
||||
@kernel
|
||||
def clock_write(self, addr, data):
|
||||
"""Write `data` to AD9516 SPI register at `addr`."""
|
||||
ad9516_write(addr, data)
|
||||
|
||||
@kernel
|
||||
def clock_read(self, addr):
|
||||
"""Read AD9516 SPI register at `addr`."""
|
||||
return ad9516_read(addr)
|
||||
|
||||
@kernel
|
||||
def jesd_enable(self, en):
|
||||
"""Enables the JESD204B core startup sequence."""
|
||||
ad9154_jesd_enable(en)
|
||||
|
||||
@kernel
|
||||
def jesd_ready(self):
|
||||
"""Returns `True` if the JESD links are up."""
|
||||
return ad9154_jesd_ready()
|
||||
|
||||
@kernel
|
||||
def jesd_prbs(self, prbs):
|
||||
ad9154_jesd_prbs(prbs)
|
||||
|
||||
@kernel
|
||||
def jesd_stpl(self, enable):
|
||||
ad9154_jesd_stpl(enable)
|
File diff suppressed because it is too large
Load Diff
@ -1,291 +0,0 @@
|
||||
# = auto-generated, do not edit
|
||||
from artiq.language.core import kernel
|
||||
|
||||
|
||||
AD9516_SERIAL_PORT_CONFIGURATION = 0x000
|
||||
AD9516_SDO_ACTIVE = 1 << 0 # 1, 0x00 R/W
|
||||
AD9516_LSB_FIRST = 1 << 1 # 1, 0x00 R/W
|
||||
AD9516_SOFT_RESET = 1 << 2 # 1, 0x00 R/W
|
||||
AD9516_LONG_INSTRUCTION = 1 << 3 # 1, 0x01 R/W
|
||||
AD9516_LONG_INSTRUCTION_MIRRORED = 1 << 4 # 1, 0x01 R/W
|
||||
AD9516_SOFT_RESET_MIRRORED = 1 << 5 # 1, 0x00 R/W
|
||||
AD9516_LSB_FIRST_MIRRORED = 1 << 6 # 1, 0x00 R/W
|
||||
AD9516_SDO_ACTIVE_MIRRORED = 1 << 7 # 1, 0x00 R/W
|
||||
|
||||
AD9516_PART_ID = 0x003
|
||||
|
||||
AD9516_READBACK_CONTROL = 0x004
|
||||
AD9516_READ_BACK_ACTIVE_REGISTERS = 1 << 0 # 1, 0x00 R/W
|
||||
|
||||
AD9516_PFD_AND_CHARGE_PUMP = 0x010
|
||||
AD9516_PLL_POWER_DOWN = 1 << 0 # 2, 0x01 R/W
|
||||
AD9516_CHARGE_PUMP_MODE = 1 << 2 # 2, 0x03 R/W
|
||||
AD9516_CHARGE_PUMP_CURRENT = 1 << 4 # 3, 0x07 R/W
|
||||
AD9516_PFD_POLARITY = 1 << 7 # 1, 0x00 R/W
|
||||
|
||||
AD9516_R_COUNTER_LSB = 0x011
|
||||
AD9516_R_COUNTER_MSB = 0x012
|
||||
|
||||
AD9516_A_COUNTER = 0x013
|
||||
|
||||
AD9516_B_COUNTER_LSB = 0x014
|
||||
AD9516_B_COUNTER_MSB = 0x015
|
||||
|
||||
AD9516_PLL_CONTROL_1 = 0x016
|
||||
AD9516_PRESCALER_P = 1 << 0 # 3, 0x06 R/W
|
||||
AD9516_B_COUNTER_BYPASS = 1 << 3 # 1, 0x00 R/W
|
||||
AD9516_RESET_ALL_COUNTERS = 1 << 4 # 1, 0x00 R/W
|
||||
AD9516_RESET_A_AND_B_COUNTERS = 1 << 5 # 1, 0x00 R/W
|
||||
AD9516_RESET_R_COUNTER = 1 << 6 # 1, 0x00 R/W
|
||||
AD9516_SET_CP_PIN_TO_VCP_2 = 1 << 7 # 1, 0x00 R/W
|
||||
|
||||
AD9516_PLL_CONTROL_2 = 0x017
|
||||
AD9516_ANTIBACKLASH_PULSE_WIDTH = 1 << 0 # 2, 0x00 R/W
|
||||
AD9516_STATUS_PIN_CONTROL = 1 << 2 # 6, 0x00 R/W
|
||||
|
||||
AD9516_PLL_CONTROL_3 = 0x018
|
||||
AD9516_VCO_CAL_NOW = 1 << 0 # 1, 0x00 R/W
|
||||
AD9516_VCO_CALIBRATION_DIVIDER = 1 << 1 # 2, 0x03 R/W
|
||||
AD9516_DISABLE_DIGITAL_LOCK_DETECT = 1 << 3 # 1, 0x00 R/W
|
||||
AD9516_DIGITAL_LOCK_DETECT_WINDOW = 1 << 4 # 1, 0x00 R/W
|
||||
AD9516_LOCK_DETECT_COUNTER = 1 << 5 # 2, 0x00 R/W
|
||||
|
||||
AD9516_PLL_CONTROL_4 = 0x019
|
||||
AD9516_N_PATH_DELAY = 1 << 0 # 3, 0x00 R/W
|
||||
AD9516_R_PATH_DELAY = 1 << 3 # 3, 0x00 R/W
|
||||
AD9516_R_A_B_COUNTERS_SYNC_PIN_RESET = 1 << 6 # 2, 0x00 R/W
|
||||
|
||||
AD9516_PLL_CONTROL_5 = 0x01a
|
||||
AD9516_LD_PIN_CONTROL = 1 << 0 # 6, 0x00 R/W
|
||||
AD9516_REFERENCE_FREQUENCY_MONITOR_THRESHOLD = 1 << 6 # 1, 0x00 R/W
|
||||
|
||||
AD9516_PLL_CONTROL_6 = 0x01b
|
||||
AD9516_REFMON_PIN_CONTROL = 1 << 0 # 5, 0x00 R/W
|
||||
AD9516_REF1_REFIN_FREQUENCY_MONITOR = 1 << 5 # 1, 0x00 R/W
|
||||
AD9516_REF2_REFIN_FREQUENCY_MONITOR = 1 << 6 # 1, 0x00 R/W
|
||||
AD9516_VCO_FREQUENCY_MONITOR = 1 << 7 # 1, 0x00 R/W
|
||||
|
||||
AD9516_PLL_CONTROL_7 = 0x01c
|
||||
AD9516_DIFFERENTIAL_REFERENCE = 1 << 0 # 1, 0x00 R/W
|
||||
AD9516_REF1_POWER_ON = 1 << 1 # 1, 0x00 R/W
|
||||
AD9516_REF2_POWER_ON = 1 << 2 # 1, 0x00 R/W
|
||||
AD9516_USE_REF_SEL_PIN = 1 << 5 # 1, 0x00 R/W
|
||||
AD9516_SELECT_REF2 = 1 << 6 # 1, 0x00 R/W
|
||||
AD9516_DISABLE_SWITCHOVER_DEGLITCH = 1 << 7 # 1, 0x00 R/W
|
||||
|
||||
AD9516_PLL_CONTROL_8 = 0x01d
|
||||
AD9516_HOLDOVER_ENABLE = 1 << 0 # 1, 0x00 R/W
|
||||
AD9516_EXTERNAL_HOLDOVER_CONTROL = 1 << 1 # 1, 0x00 R/W
|
||||
AD9516_HOLDOVER_ENABLEreg001D = 1 << 2 # 1, 0x00 R/W
|
||||
AD9516_LD_PIN_COMPARATOR_ENABLE = 1 << 3 # 1, 0x00 R/W
|
||||
AD9516_PLL_STATUS_REGISTER_DISABLE = 1 << 4 # 1, 0x00 R/W
|
||||
|
||||
AD9516_PLL_READBACK = 0x01f
|
||||
AD9516_DIGITAL_LOCK_DETECT = 1 << 0 # 1, 0x00 R
|
||||
AD9516_REF1_FREQUENCY_THRESHOLD = 1 << 1 # 1, 0x00 R
|
||||
AD9516_REF2_FREQUENCY_THRESHOLD = 1 << 2 # 1, 0x00 R
|
||||
AD9516_VCO_FREQUENCY_THRESHOLD = 1 << 3 # 1, 0x00 R
|
||||
AD9516_REF2_SELECTED = 1 << 4 # 1, 0x00 R
|
||||
AD9516_HOLDOVER_ACTIVE = 1 << 5 # 1, 0x00 R
|
||||
AD9516_VCO_CAL_FINISHED = 1 << 6 # 1, 0x00 R
|
||||
|
||||
AD9516_OUT6_DELAY_BYPASS = 0x0a0
|
||||
|
||||
AD9516_OUT6_DELAY_FULL_SCALE = 0x0a1
|
||||
AD9516_OUT6_RAMP_CURRENT = 1 << 0 # 3, 0x00 R/W
|
||||
AD9516_OUT6_RAMP_CAPACITORS = 1 << 3 # 3, 0x00 R/W
|
||||
|
||||
AD9516_OUT6_DELAY_FRACTION = 0x0a2
|
||||
|
||||
AD9516_OUT7_DELAY_BYPASS = 0x0a3
|
||||
|
||||
AD9516_OUT7_DELAY_FULL_SCALE = 0x0a4
|
||||
AD9516_OUT7_RAMP_CURRENT = 1 << 0 # 3, 0x00 R/W
|
||||
AD9516_OUT7_RAMP_CAPACITORS = 1 << 3 # 3, 0x00 R/W
|
||||
|
||||
AD9516_OUT7_DELAY_FRACTION = 0x0a5
|
||||
|
||||
AD9516_OUT8_DELAY_BYPASS = 0x0a6
|
||||
|
||||
AD9516_OUT8_DELAY_FULL_SCALE = 0x0a7
|
||||
AD9516_OUT8_RAMP_CURRENT = 1 << 0 # 3, 0x00 R/W
|
||||
AD9516_OUT8_RAMP_CAPACITORS = 1 << 3 # 3, 0x00 R/W
|
||||
|
||||
AD9516_OUT8_DELAY_FRACTION = 0x0a8
|
||||
|
||||
AD9516_OUT9_DELAY_BYPASS = 0x0a9
|
||||
|
||||
AD9516_OUT9_DELAY_FULL_SCALE = 0x0aa
|
||||
AD9516_OUT9_RAMP_CURRENT = 1 << 0 # 3, 0x00 R/W
|
||||
AD9516_OUT9_RAMP_CAPACITORS = 1 << 3 # 3, 0x00 R/W
|
||||
|
||||
AD9516_OUT9_DELAY_FRACTION = 0x0ab
|
||||
|
||||
AD9516_OUT0 = 0x0f0
|
||||
AD9516_OUT0_POWER_DOWN = 1 << 0 # 2, 0x00 R/W
|
||||
AD9516_OUT0_LVPECL_DIFFERENTIAL_VOLTAGE = 1 << 2 # 2, 0x02 R/W
|
||||
AD9516_OUT0_INVERT = 1 << 4 # 1, 0x00 R/W
|
||||
|
||||
AD9516_OUT1 = 0x0f1
|
||||
AD9516_OUT1_POWER_DOWN = 1 << 0 # 2, 0x02 R/W
|
||||
AD9516_OUT1_LVPECLDIFFERENTIAL_VOLTAGE = 1 << 2 # 2, 0x02 R/W
|
||||
AD9516_OUT1_INVERT = 1 << 4 # 1, 0x00 R/W
|
||||
|
||||
AD9516_OUT2 = 0x0f2
|
||||
AD9516_OUT2_POWER_DOWN = 1 << 0 # 2, 0x00 R/W
|
||||
AD9516_OUT2_LVPECL_DIFFERENTIAL_VOLTAGE = 1 << 2 # 2, 0x02 R/W
|
||||
AD9516_OUT2_INVERT = 1 << 4 # 1, 0x00 R/W
|
||||
|
||||
AD9516_OUT3 = 0x0f3
|
||||
AD9516_OUT3_POWER_DOWN = 1 << 0 # 2, 0x02 R/W
|
||||
AD9516_OUT3_LVPECL_DIFFERENTIAL_VOLTAGE = 1 << 2 # 2, 0x02 R/W
|
||||
AD9516_OUT3_INVERT = 1 << 4 # 1, 0x00 R/W
|
||||
|
||||
AD9516_OUT4 = 0x0f4
|
||||
AD9516_OUT4_POWER_DOWN = 1 << 0 # 2, 0x02 R/W
|
||||
AD9516_OUT4_LVPECL_DIFFERENTIAL_VOLTAGE = 1 << 2 # 2, 0x02 R/W
|
||||
AD9516_OUT4_INVERT = 1 << 4 # 1, 0x00 R/W
|
||||
|
||||
AD9516_OUT5 = 0x0f5
|
||||
AD9516_OUT5_POWER_DOWN = 1 << 0 # 2, 0x02 R/W
|
||||
AD9516_OUT5_LVPECL_DIFFERENTIAL_VOLTAGE = 1 << 2 # 2, 0x02 R/W
|
||||
AD9516_OUT5_INVERT = 1 << 4 # 1, 0x00 R/W
|
||||
|
||||
AD9516_OUT6 = 0x140
|
||||
AD9516_OUT6_POWER_DOWN = 1 << 0 # 1, 0x00 R/W
|
||||
AD9516_OUT6_LVDS_OUTPUT_CURRENT = 1 << 1 # 2, 0x01 R/W
|
||||
AD9516_OUT6_SELECT_LVDS_CMOS = 1 << 3 # 1, 0x00 R/W
|
||||
AD9516_OUT6_CMOS_B = 1 << 4 # 1, 0x00 R/W
|
||||
AD9516_OUT6_LVDS_CMOS_OUTPUT_POLARITY = 1 << 5 # 1, 0x00 R/W
|
||||
AD9516_OUT6_CMOS_OUTPUT_POLARITY = 1 << 6 # 2, 0x01 R/W
|
||||
|
||||
AD9516_OUT7 = 0x141
|
||||
AD9516_OUT7_POWER_DOWN = 1 << 0 # 1, 0x01 R/W
|
||||
AD9516_OUT7_LVDS_OUTPUT_CURRENT = 1 << 1 # 2, 0x01 R/W
|
||||
AD9516_OUT7_SELECT_LVDS_CMOS = 1 << 3 # 1, 0x00 R/W
|
||||
AD9516_OUT7_CMOS_B = 1 << 4 # 1, 0x00 R/W
|
||||
AD9516_OUT7_LVDS_CMOS_OUTPUT_POLARITY = 1 << 5 # 1, 0x00 R/W
|
||||
AD9516_OUT7_CMOS_OUTPUT_POLARITY = 1 << 6 # 2, 0x01 R/W
|
||||
|
||||
AD9516_OUT8 = 0x142
|
||||
AD9516_OUT8_POWER_DOWN = 1 << 0 # 1, 0x00 R/W
|
||||
AD9516_OUT8_LVDS_OUTPUT_CURRENT = 1 << 1 # 2, 0x01 R/W
|
||||
AD9516_OUT8_SELECT_LVDS_CMOS = 1 << 3 # 1, 0x00 R/W
|
||||
AD9516_OUT8_CMOS_B = 1 << 4 # 1, 0x00 R/W
|
||||
AD9516_OUT8_LVDS_CMOS_OUTPUT_POLARITY = 1 << 5 # 1, 0x00 R/W
|
||||
AD9516_OUT8_CMOS_OUTPUT_POLARITY = 1 << 6 # 2, 0x01 R/W
|
||||
|
||||
AD9516_OUT9 = 0x143
|
||||
AD9516_OUT9_POWER_DOWN = 1 << 0 # 1, 0x01 R/W
|
||||
AD9516_OUT9_LVDS_OUTPUT_CURRENT = 1 << 1 # 2, 0x01 R/W
|
||||
AD9516_OUT9_SELECT_LVDS_CMOS = 1 << 3 # 1, 0x00 R/W
|
||||
AD9516_OUT9_CMOS_B = 1 << 4 # 1, 0x00 R/W
|
||||
AD9516_OUT9_LVDS_CMOS_OUTPUT_POLARITY = 1 << 5 # 1, 0x00 R/W
|
||||
AD9516_OUT9_CMOS_OUTPUT_POLARITY = 1 << 6 # 2, 0x01 R/W
|
||||
|
||||
AD9516_DIVIDER_0_0 = 0x190
|
||||
AD9516_DIVIDER_0_HIGH_CYCLES = 1 << 0 # 4, 0x00 R/W
|
||||
AD9516_DIVIDER_0_LOW_CYCLES = 1 << 4 # 4, 0x00 R/W
|
||||
|
||||
AD9516_DIVIDER_0_1 = 0x191
|
||||
AD9516_DIVIDER_0_PHASE_OFFSET = 1 << 0 # 4, 0x00 R/W
|
||||
AD9516_DIVIDER_0_START_HIGH = 1 << 4 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_0_FORCE_HIGH = 1 << 5 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_0_NOSYNC = 1 << 6 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_0_BYPASS = 1 << 7 # 1, 0x01 R/W
|
||||
|
||||
AD9516_DIVIDER_0_2 = 0x192
|
||||
AD9516_DIVIDER_0_DCCOFF = 1 << 0 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_0_DIRECT_TO_OUTPUT = 1 << 1 # 1, 0x00 R/W
|
||||
|
||||
AD9516_DIVIDER_1_0 = 0x193
|
||||
AD9516_DIVIDER_1_HIGH_CYCLES = 1 << 0 # 4, 0x00 R/W
|
||||
AD9516_DIVIDER_1_LOW_CYCLES = 1 << 4 # 4, 0x00 R/W
|
||||
|
||||
AD9516_DIVIDER_1_1 = 0x194
|
||||
AD9516_DIVIDER_1_PHASE_OFFSET = 1 << 0 # 4, 0x00 R/W
|
||||
AD9516_DIVIDER_1_START_HIGH = 1 << 4 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_1_FORCE_HIGH = 1 << 5 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_1_NOSYNC = 1 << 6 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_1_BYPASS = 1 << 7 # 1, 0x00 R/W
|
||||
|
||||
AD9516_DIVIDER_1_2 = 0x195
|
||||
AD9516_DIVIDER_1_DCCOFF = 1 << 0 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_1_DIRECT_TO_OUTPUT = 1 << 1 # 1, 0x00 R/W
|
||||
|
||||
AD9516_DIVIDER_2_0 = 0x196
|
||||
AD9516_DIVIDER_2_HIGH_CYCLES = 1 << 0 # 4, 0x00 R/W
|
||||
AD9516_DIVIDER_2_LOW_CYCLES = 1 << 4 # 4, 0x00 R/W
|
||||
|
||||
AD9516_DIVIDER_2_1 = 0x197
|
||||
AD9516_DIVIDER_2_PHASE_OFFSET = 1 << 0 # 4, 0x00 R/W
|
||||
AD9516_DIVIDER_2_START_HIGH = 1 << 4 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_2_FORCE_HIGH = 1 << 5 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_2_NOSYNC = 1 << 6 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_2_BYPASS = 1 << 7 # 1, 0x00 R/W
|
||||
|
||||
AD9516_DIVIDER_2_2 = 0x198
|
||||
AD9516_DIVIDER_2_DCCOFF = 1 << 0 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_2_DIRECT_TO_OUTPUT = 1 << 1 # 1, 0x00 R/W
|
||||
|
||||
AD9516_DIVIDER_3_0 = 0x199
|
||||
AD9516_DIVIDER_3_HIGH_CYCLES_1 = 1 << 0 # 4, 0x02 R/W
|
||||
AD9516_DIVIDER_3_LOW_CYCLES_1 = 1 << 4 # 4, 0x02 R/W
|
||||
|
||||
AD9516_DIVIDER_3_1 = 0x19a
|
||||
AD9516_DIVIDER_3_PHASE_OFFSET_1 = 1 << 0 # 4, 0x00 R/W
|
||||
AD9516_DIVIDER_3_PHASE_OFFSET_2 = 1 << 4 # 4, 0x00 R/W
|
||||
|
||||
AD9516_DIVIDER_3_2 = 0x19b
|
||||
AD9516_DIVIDER_3_HIGH_CYCLES_2 = 1 << 0 # 4, 0x01 R/W
|
||||
AD9516_DIVIDER_3_LOW_CYCLES_2 = 1 << 4 # 4, 0x01 R/W
|
||||
|
||||
AD9516_DIVIDER_3_3 = 0x19c
|
||||
AD9516_DIVIDER_3_START_HIGH_1 = 1 << 0 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_3_START_HIGH_2 = 1 << 1 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_3_FORCE_HIGH = 1 << 2 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_3_NOSYNC = 1 << 3 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_3_BYPASS_1 = 1 << 4 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_3_BYPASS_2 = 1 << 5 # 1, 0x00 R/W
|
||||
|
||||
AD9516_DIVIDER_3_4 = 0x19d
|
||||
AD9516_DIVIDER_3_DCCOFF = 1 << 0 # 1, 0x00 R/W
|
||||
|
||||
AD9516_DIVIDER_4_0 = 0x19e
|
||||
AD9516_DIVIDER_4_HIGH_CYCLES_1 = 1 << 0 # 4, 0x02 R/W
|
||||
AD9516_DIVIDER_4_LOW_CYCLES_1 = 1 << 4 # 4, 0x02 R/W
|
||||
|
||||
AD9516_DIVIDER_4_1 = 0x19f
|
||||
AD9516_DIVIDER_4_PHASE_OFFSET_1 = 1 << 0 # 4, 0x00 R/W
|
||||
AD9516_DIVIDER_4_PHASE_OFFSET_2 = 1 << 4 # 4, 0x00 R/W
|
||||
|
||||
AD9516_DIVIDER_4_2 = 0x1a0
|
||||
AD9516_DIVIDER_4_HIGH_CYCLES_2 = 1 << 0 # 4, 0x01 R/W
|
||||
AD9516_DIVIDER_4_LOW_CYCLES_2 = 1 << 4 # 4, 0x01 R/W
|
||||
|
||||
AD9516_DIVIDER_4_3 = 0x1a1
|
||||
AD9516_DIVIDER_4_START_HIGH_1 = 1 << 0 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_4_START_HIGH_2 = 1 << 1 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_4_FORCE_HIGH = 1 << 2 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_4_NOSYNC = 1 << 3 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_4_BYPASS_1 = 1 << 4 # 1, 0x00 R/W
|
||||
AD9516_DIVIDER_4_BYPASS_2 = 1 << 5 # 1, 0x00 R/W
|
||||
|
||||
AD9516_DIVIDER_4_4 = 0x1a2
|
||||
AD9516_DIVIDER_4_DCCOFF = 1 << 0 # 1, 0x00 R/W
|
||||
|
||||
AD9516_VCO_DIVIDER = 0x1e0
|
||||
|
||||
AD9516_INPUT_CLKS = 0x1e1
|
||||
AD9516_BYPASS_VCO_DIVIDER = 1 << 0 # 1, 0x00 R/W
|
||||
AD9516_SELECT_VCO_OR_CLK = 1 << 1 # 1, 0x00 R/W
|
||||
AD9516_POWER_DOWN_VCO_AND_CLK = 1 << 2 # 1, 0x00 R/W
|
||||
AD9516_POWER_DOWN_VCO_CLOCK_INTERFACE = 1 << 3 # 1, 0x00 R/W
|
||||
AD9516_POWER_DOWN_CLOCK_INPUT_SECTION = 1 << 4 # 1, 0x00 R/W
|
||||
|
||||
AD9516_POWER_DOWN_AND_SYNC = 0x230
|
||||
AD9516_SOFT_SYNC = 1 << 0 # 1, 0x00 R/W
|
||||
AD9516_POWER_DOWN_DISTRIBUTION_REFERENCE = 1 << 1 # 1, 0x00 R/W
|
||||
AD9516_POWER_DOWN_SYNC = 1 << 2 # 1, 0x00 R/W
|
||||
|
||||
AD9516_UPDATE_ALL_REGISTERS = 0x232
|
@ -12,8 +12,7 @@
|
||||
"module": "artiq.coredevice.core",
|
||||
"class": "Core",
|
||||
"arguments": {
|
||||
"ref_period": 5e-9/6,
|
||||
"external_clock": True
|
||||
"ref_period": 5e-9/6
|
||||
}
|
||||
},
|
||||
"core_cache": {
|
||||
@ -21,11 +20,6 @@
|
||||
"module": "artiq.coredevice.cache",
|
||||
"class": "CoreCache"
|
||||
},
|
||||
"ad9154": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.ad9154",
|
||||
"class": "AD9154"
|
||||
},
|
||||
"ttl_sma": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
@ -44,34 +38,28 @@
|
||||
"class": "TTLInOut",
|
||||
"arguments": {"channel": 2}
|
||||
},
|
||||
"sync": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.ttl",
|
||||
"class": "TTLInOut",
|
||||
"arguments": {"channel": 3}
|
||||
},
|
||||
"sawg0": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.sawg",
|
||||
"class": "SAWG",
|
||||
"arguments": {"channel_base": 4, "parallelism": 2}
|
||||
"arguments": {"channel_base": 3, "parallelism": 2}
|
||||
},
|
||||
"sawg1": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.sawg",
|
||||
"class": "SAWG",
|
||||
"arguments": {"channel_base": 14, "parallelism": 2}
|
||||
"arguments": {"channel_base": 13, "parallelism": 2}
|
||||
},
|
||||
"sawg2": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.sawg",
|
||||
"class": "SAWG",
|
||||
"arguments": {"channel_base": 24, "parallelism": 2}
|
||||
"arguments": {"channel_base": 23, "parallelism": 2}
|
||||
},
|
||||
"sawg3": {
|
||||
"type": "local",
|
||||
"module": "artiq.coredevice.sawg",
|
||||
"class": "SAWG",
|
||||
"arguments": {"channel_base": 34, "parallelism": 2}
|
||||
"arguments": {"channel_base": 33, "parallelism": 2}
|
||||
}
|
||||
}
|
||||
|
@ -1,362 +0,0 @@
|
||||
from jesd204b.common import (JESD204BPhysicalSettings,
|
||||
JESD204BTransportSettings,
|
||||
JESD204BSettings)
|
||||
from artiq.experiment import *
|
||||
from artiq.coredevice.ad9154_reg import *
|
||||
|
||||
# ad9154 mode 2:
|
||||
ps = JESD204BPhysicalSettings(
|
||||
l=4, # lanes
|
||||
m=4, # converters
|
||||
n=16, # bits/converter
|
||||
np=16, # bits/sample
|
||||
)
|
||||
ts = JESD204BTransportSettings(
|
||||
f=2, # octets/(lane and frame)
|
||||
s=1, # samples/(converter and frame)
|
||||
k=16, # frames/multiframe
|
||||
cs=1, #
|
||||
)
|
||||
jesd_settings = JESD204BSettings(ps, ts, did=0x5a, bid=0x5)
|
||||
jesd_checksum = jesd_settings.get_configuration_checksum()
|
||||
# external clk=300MHz
|
||||
# pclock=150MHz
|
||||
# deviceclock_fpga=150MHz
|
||||
# deviceclock_dac=300MHz
|
||||
|
||||
|
||||
class DACSetup(EnvExperiment):
|
||||
def build(self):
|
||||
self.setattr_device("core")
|
||||
self.setattr_device("led")
|
||||
self.setattr_device("ad9154")
|
||||
self.setattr_device("sync")
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
# TODO; remove when
|
||||
# https://github.com/m-labs/jesd204b/issues/6
|
||||
# is resolved
|
||||
for i in range(99):
|
||||
try:
|
||||
self.cfg()
|
||||
return
|
||||
except:
|
||||
pass
|
||||
self.cfg()
|
||||
|
||||
@kernel
|
||||
def cfg(self):
|
||||
self.core.reset()
|
||||
self.ad9154.jesd_enable(0)
|
||||
self.ad9154.jesd_prbs(0)
|
||||
self.ad9154.jesd_stpl(0)
|
||||
self.busywait_us(10000)
|
||||
self.ad9154.jesd_enable(1)
|
||||
self.ad9154.init()
|
||||
self.dac_setup()
|
||||
self.ad9154.jesd_enable(0)
|
||||
self.busywait_us(10000)
|
||||
self.ad9154.jesd_enable(1)
|
||||
self.monitor()
|
||||
while not self.ad9154.jesd_ready():
|
||||
pass
|
||||
self.busywait_us(10000)
|
||||
if self.ad9154.dac_read(AD9154_CODEGRPSYNCFLG) != 0x0f:
|
||||
raise ValueError("bad CODEGRPSYNCFLG")
|
||||
self.core.break_realtime()
|
||||
if not self.sync.sample_get_nonrt():
|
||||
raise ValueError("bad SYNC")
|
||||
if self.ad9154.dac_read(AD9154_FRAMESYNCFLG) != 0x0f:
|
||||
raise ValueError("bad FRAMESYNCFLG")
|
||||
if self.ad9154.dac_read(AD9154_GOODCHKSUMFLG) != 0x0f:
|
||||
raise ValueError("bad GOODCHECKSUMFLG")
|
||||
if self.ad9154.dac_read(AD9154_INITLANESYNCFLG) != 0x0f:
|
||||
raise ValueError("bad INITLANESYNCFLG")
|
||||
|
||||
@kernel
|
||||
def busywait_us(self, t):
|
||||
t = self.core.get_rtio_counter_mu() + self.core.seconds_to_mu(t*us)
|
||||
while self.core.get_rtio_counter_mu() < t:
|
||||
pass
|
||||
|
||||
@kernel
|
||||
def dac_setup(self):
|
||||
# reset
|
||||
self.ad9154.dac_write(AD9154_SPI_INTFCONFA,
|
||||
AD9154_SOFTRESET_M_SET(1) | AD9154_SOFTRESET_SET(1) |
|
||||
AD9154_LSBFIRST_M_SET(0) | AD9154_LSBFIRST_SET(0) |
|
||||
AD9154_ADDRINC_M_SET(0) | AD9154_ADDRINC_SET(0) |
|
||||
AD9154_SDOACTIVE_M_SET(1) | AD9154_SDOACTIVE_SET(1))
|
||||
self.busywait_us(100)
|
||||
self.ad9154.dac_write(AD9154_SPI_INTFCONFA,
|
||||
AD9154_SOFTRESET_M_SET(0) | AD9154_SOFTRESET_SET(0) |
|
||||
AD9154_LSBFIRST_M_SET(0) | AD9154_LSBFIRST_SET(0) |
|
||||
AD9154_ADDRINC_M_SET(0) | AD9154_ADDRINC_SET(0) |
|
||||
AD9154_SDOACTIVE_M_SET(1) | AD9154_SDOACTIVE_SET(1))
|
||||
self.busywait_us(100)
|
||||
if ((self.ad9154.dac_read(AD9154_PRODIDH) << 8) |
|
||||
self.ad9154.dac_read(AD9154_PRODIDL) != 0x9154):
|
||||
raise ValueError("AD9154 not found")
|
||||
|
||||
self.ad9154.dac_write(AD9154_PWRCNTRL0,
|
||||
AD9154_PD_DAC0_SET(0) | AD9154_PD_DAC1_SET(0) |
|
||||
AD9154_PD_DAC2_SET(0) | AD9154_PD_DAC3_SET(0) |
|
||||
AD9154_PD_BG_SET(0))
|
||||
self.busywait_us(100)
|
||||
self.ad9154.dac_write(AD9154_TXENMASK1, AD9154_DACA_MASK_SET(0) |
|
||||
AD9154_DACB_MASK_SET(0)) # TX not controlled by TXEN pins
|
||||
self.ad9154.dac_write(AD9154_CLKCFG0,
|
||||
AD9154_REF_CLKDIV_EN_SET(0) | AD9154_RF_SYNC_EN_SET(1) |
|
||||
AD9154_DUTY_EN_SET(1) | AD9154_PD_CLK_REC_SET(0) |
|
||||
AD9154_PD_SERDES_PCLK_SET(0) | AD9154_PD_CLK_DIG_SET(0) |
|
||||
AD9154_PD_CLK23_SET(0) | AD9154_PD_CLK01_SET(0))
|
||||
self.ad9154.dac_write(AD9154_DACPLLCNTRL,
|
||||
AD9154_ENABLE_DACPLL_SET(0) | AD9154_RECAL_DACPLL_SET(0))
|
||||
self.ad9154.dac_write(AD9154_SYSREF_ACTRL0, # jesd204b subclass 1
|
||||
AD9154_HYS_CNTRL1_SET(0) | AD9154_SYSREF_RISE_SET(0) |
|
||||
AD9154_HYS_ON_SET(0) | AD9154_PD_SYSREF_BUFFER_SET(0))
|
||||
|
||||
self.ad9154.dac_write(AD9154_DEVICE_CONFIG_REG_0, 0x8b) # magic
|
||||
self.ad9154.dac_write(AD9154_DEVICE_CONFIG_REG_1, 0x01) # magic
|
||||
self.ad9154.dac_write(AD9154_DEVICE_CONFIG_REG_2, 0x01) # magic
|
||||
|
||||
self.ad9154.dac_write(AD9154_SPI_PAGEINDX, 0x3) # A and B dual
|
||||
|
||||
self.ad9154.dac_write(AD9154_INTERP_MODE, 0) # 1x
|
||||
self.ad9154.dac_write(AD9154_MIX_MODE, 0)
|
||||
self.ad9154.dac_write(AD9154_DATA_FORMAT, AD9154_BINARY_FORMAT_SET(0)) # s16
|
||||
self.ad9154.dac_write(AD9154_DATAPATH_CTRL,
|
||||
AD9154_I_TO_Q_SET(0) | AD9154_SEL_SIDEBAND_SET(0) |
|
||||
AD9154_MODULATION_TYPE_SET(0) | AD9154_PHASE_ADJ_ENABLE_SET(0) |
|
||||
AD9154_DIG_GAIN_ENABLE_SET(1) | AD9154_INVSINC_ENABLE_SET(0))
|
||||
self.ad9154.dac_write(AD9154_IDAC_DIG_GAIN0, 0x00)
|
||||
self.ad9154.dac_write(AD9154_IDAC_DIG_GAIN1, 0x8)
|
||||
self.ad9154.dac_write(AD9154_QDAC_DIG_GAIN0, 0x00)
|
||||
self.ad9154.dac_write(AD9154_QDAC_DIG_GAIN1, 0x8)
|
||||
self.ad9154.dac_write(AD9154_DC_OFFSET_CTRL, 0)
|
||||
self.ad9154.dac_write(AD9154_IPATH_DC_OFFSET_1PART0, 0x00)
|
||||
self.ad9154.dac_write(AD9154_IPATH_DC_OFFSET_1PART1, 0x00)
|
||||
self.ad9154.dac_write(AD9154_IPATH_DC_OFFSET_2PART, 0x00)
|
||||
self.ad9154.dac_write(AD9154_QPATH_DC_OFFSET_1PART0, 0x00)
|
||||
self.ad9154.dac_write(AD9154_QPATH_DC_OFFSET_1PART1, 0x00)
|
||||
self.ad9154.dac_write(AD9154_QPATH_DC_OFFSET_2PART, 0x00)
|
||||
self.ad9154.dac_write(AD9154_PHASE_ADJ0, 0)
|
||||
self.ad9154.dac_write(AD9154_PHASE_ADJ1, 0)
|
||||
self.ad9154.dac_write(AD9154_GROUP_DLY, AD9154_COARSE_GROUP_DELAY_SET(0x8) |
|
||||
AD9154_GROUP_DELAY_RESERVED_SET(0x8))
|
||||
self.ad9154.dac_write(AD9154_GROUPDELAY_COMP_BYP,
|
||||
AD9154_GROUPCOMP_BYPQ_SET(1) |
|
||||
AD9154_GROUPCOMP_BYPI_SET(1))
|
||||
self.ad9154.dac_write(AD9154_GROUPDELAY_COMP_I, 0)
|
||||
self.ad9154.dac_write(AD9154_GROUPDELAY_COMP_Q, 0)
|
||||
self.ad9154.dac_write(AD9154_PDP_AVG_TIME, AD9154_PDP_ENABLE_SET(0))
|
||||
|
||||
self.ad9154.dac_write(AD9154_MASTER_PD, 0)
|
||||
self.ad9154.dac_write(AD9154_PHY_PD, 0x0f) # power down lanes 0-3
|
||||
self.ad9154.dac_write(AD9154_GENERIC_PD,
|
||||
AD9154_PD_SYNCOUT0B_SET(0) |
|
||||
AD9154_PD_SYNCOUT1B_SET(1))
|
||||
self.ad9154.dac_write(AD9154_GENERAL_JRX_CTRL_0,
|
||||
AD9154_LINK_EN_SET(0x0) | AD9154_LINK_PAGE_SET(0) |
|
||||
AD9154_LINK_MODE_SET(0) | AD9154_CHECKSUM_MODE_SET(0))
|
||||
self.ad9154.dac_write(AD9154_ILS_DID, jesd_settings.did)
|
||||
self.ad9154.dac_write(AD9154_ILS_BID, jesd_settings.bid)
|
||||
self.ad9154.dac_write(AD9154_ILS_LID0, 0x00) # lane id
|
||||
self.ad9154.dac_write(AD9154_ILS_SCR_L,
|
||||
AD9154_L_1_SET(jesd_settings.phy.l - 1) |
|
||||
AD9154_SCR_SET(1))
|
||||
self.ad9154.dac_write(AD9154_ILS_F, jesd_settings.transport.f - 1)
|
||||
self.ad9154.dac_write(AD9154_ILS_K, jesd_settings.transport.k - 1)
|
||||
self.ad9154.dac_write(AD9154_ILS_M, jesd_settings.phy.m - 1)
|
||||
self.ad9154.dac_write(AD9154_ILS_CS_N,
|
||||
AD9154_N_1_SET(jesd_settings.phy.n - 1) |
|
||||
AD9154_CS_SET(0))
|
||||
self.ad9154.dac_write(AD9154_ILS_NP,
|
||||
AD9154_NP_1_SET(jesd_settings.phy.np - 1) |
|
||||
AD9154_SUBCLASSV_SET(jesd_settings.phy.subclassv))
|
||||
self.ad9154.dac_write(AD9154_ILS_S,
|
||||
AD9154_S_1_SET(jesd_settings.transport.s - 1) |
|
||||
AD9154_JESDV_SET(jesd_settings.phy.jesdv))
|
||||
self.ad9154.dac_write(AD9154_ILS_HD_CF,
|
||||
AD9154_HD_SET(0) | AD9154_CF_SET(0))
|
||||
self.ad9154.dac_write(AD9154_ILS_CHECKSUM, jesd_checksum)
|
||||
self.ad9154.dac_write(AD9154_LANEDESKEW, 0x0f)
|
||||
for i in range(8):
|
||||
self.ad9154.dac_write(AD9154_BADDISPARITY, AD9154_RST_IRQ_DIS_SET(0) |
|
||||
AD9154_DISABLE_ERR_CNTR_DIS_SET(0) |
|
||||
AD9154_RST_ERR_CNTR_DIS_SET(1) | AD9154_LANE_ADDR_DIS_SET(i))
|
||||
self.ad9154.dac_write(AD9154_BADDISPARITY, AD9154_RST_IRQ_DIS_SET(0) |
|
||||
AD9154_DISABLE_ERR_CNTR_DIS_SET(0) |
|
||||
AD9154_RST_ERR_CNTR_DIS_SET(0) | AD9154_LANE_ADDR_DIS_SET(i))
|
||||
self.ad9154.dac_write(AD9154_NIT_W, AD9154_RST_IRQ_NIT_SET(0) |
|
||||
AD9154_DISABLE_ERR_CNTR_NIT_SET(0) |
|
||||
AD9154_RST_ERR_CNTR_NIT_SET(1) | AD9154_LANE_ADDR_NIT_SET(i))
|
||||
self.ad9154.dac_write(AD9154_NIT_W, AD9154_RST_IRQ_NIT_SET(0) |
|
||||
AD9154_DISABLE_ERR_CNTR_NIT_SET(0) |
|
||||
AD9154_RST_ERR_CNTR_NIT_SET(0) | AD9154_LANE_ADDR_NIT_SET(i))
|
||||
self.ad9154.dac_write(AD9154_UNEXPECTEDCONTROL_W, AD9154_RST_IRQ_UCC_SET(0) |
|
||||
AD9154_DISABLE_ERR_CNTR_UCC_SET(0) |
|
||||
AD9154_RST_ERR_CNTR_UCC_SET(1) | AD9154_LANE_ADDR_UCC_SET(i))
|
||||
self.ad9154.dac_write(AD9154_BADDISPARITY, AD9154_RST_IRQ_UCC_SET(0) |
|
||||
AD9154_DISABLE_ERR_CNTR_UCC_SET(0) |
|
||||
AD9154_RST_ERR_CNTR_UCC_SET(0) | AD9154_LANE_ADDR_UCC_SET(i))
|
||||
self.ad9154.dac_write(AD9154_CTRLREG1, jesd_settings.transport.f)
|
||||
self.ad9154.dac_write(AD9154_CTRLREG2, AD9154_ILAS_MODE_SET(0) |
|
||||
AD9154_THRESHOLD_MASK_EN_SET(0))
|
||||
self.ad9154.dac_write(AD9154_KVAL, 1) # *4*K multiframes during ILAS
|
||||
self.ad9154.dac_write(AD9154_LANEENABLE, 0x0f) # CGS _after_ this
|
||||
|
||||
self.ad9154.dac_write(AD9154_TERM_BLK1_CTRLREG0, 1)
|
||||
self.ad9154.dac_write(AD9154_TERM_BLK2_CTRLREG0, 1)
|
||||
self.ad9154.dac_write(AD9154_SERDES_SPI_REG, 1)
|
||||
self.ad9154.dac_write(AD9154_CDR_OPERATING_MODE_REG_0,
|
||||
AD9154_CDR_OVERSAMP_SET(0) | AD9154_CDR_RESERVED_SET(0x2) |
|
||||
AD9154_ENHALFRATE_SET(1))
|
||||
self.ad9154.dac_write(AD9154_CDR_RESET, 0)
|
||||
self.ad9154.dac_write(AD9154_CDR_RESET, 1)
|
||||
self.ad9154.dac_write(AD9154_REF_CLK_DIVIDER_LDO,
|
||||
AD9154_SPI_CDR_OVERSAMP_SET(0x0) |
|
||||
AD9154_SPI_LDO_BYPASS_FILT_SET(1) |
|
||||
AD9154_SPI_LDO_REF_SEL_SET(0))
|
||||
self.ad9154.dac_write(AD9154_LDO_FILTER_1, 0x62) # magic
|
||||
self.ad9154.dac_write(AD9154_LDO_FILTER_2, 0xc9) # magic
|
||||
self.ad9154.dac_write(AD9154_LDO_FILTER_3, 0x0e) # magic
|
||||
self.ad9154.dac_write(AD9154_CP_CURRENT_SPI,
|
||||
AD9154_SPI_CP_CURRENT_SET(0x12) |
|
||||
AD9154_SPI_SERDES_LOGEN_POWER_MODE_SET(0))
|
||||
self.ad9154.dac_write(AD9154_VCO_LDO, 0x7b) # magic
|
||||
self.ad9154.dac_write(AD9154_PLL_RD_REG,
|
||||
AD9154_SPI_SERDES_LOGEN_PD_CORE_SET(0) |
|
||||
AD9154_SPI_SERDES_LDO_PD_SET(0) | AD9154_SPI_SYN_PD_SET(0) |
|
||||
AD9154_SPI_VCO_PD_ALC_SET(0) | AD9154_SPI_VCO_PD_PTAT_SET(0) |
|
||||
AD9154_SPI_VCO_PD_SET(0))
|
||||
self.ad9154.dac_write(AD9154_ALC_VARACTOR,
|
||||
AD9154_SPI_VCO_VARACTOR_SET(0x9) |
|
||||
AD9154_SPI_INIT_ALC_VALUE_SET(0x8))
|
||||
self.ad9154.dac_write(AD9154_VCO_OUTPUT,
|
||||
AD9154_SPI_VCO_OUTPUT_LEVEL_SET(0xc) |
|
||||
AD9154_SPI_VCO_OUTPUT_RESERVED_SET(0x4))
|
||||
self.ad9154.dac_write(AD9154_CP_CONFIG,
|
||||
AD9154_SPI_CP_TEST_SET(0) |
|
||||
AD9154_SPI_CP_CAL_EN_SET(1) |
|
||||
AD9154_SPI_CP_FORCE_CALBITS_SET(0) |
|
||||
AD9154_SPI_CP_OFFSET_OFF_SET(0) |
|
||||
AD9154_SPI_CP_ENABLE_MACHINE_SET(1) |
|
||||
AD9154_SPI_CP_DITHER_MODE_SET(0) |
|
||||
AD9154_SPI_CP_HALF_VCO_CAL_CLK_SET(0))
|
||||
self.ad9154.dac_write(AD9154_VCO_BIAS_1,
|
||||
AD9154_SPI_VCO_BIAS_REF_SET(0x3) |
|
||||
AD9154_SPI_VCO_BIAS_TCF_SET(0x3))
|
||||
self.ad9154.dac_write(AD9154_VCO_BIAS_2,
|
||||
AD9154_SPI_PRESCALE_BIAS_SET(0x1) |
|
||||
AD9154_SPI_LAST_ALC_EN_SET(1) |
|
||||
AD9154_SPI_PRESCALE_BYPASS_R_SET(0x1) |
|
||||
AD9154_SPI_VCO_COMP_BYPASS_BIASR_SET(0) |
|
||||
AD9154_SPI_VCO_BYPASS_DAC_R_SET(0))
|
||||
self.ad9154.dac_write(AD9154_VCO_PD_OVERRIDES,
|
||||
AD9154_SPI_VCO_PD_OVERRIDE_VCO_BUF_SET(0) |
|
||||
AD9154_SPI_VCO_PD_OVERRIDE_CAL_TCF_SET(1) |
|
||||
AD9154_SPI_VCO_PD_OVERRIDE_VAR_REF_TCF_SET(0) |
|
||||
AD9154_SPI_VCO_PD_OVERRIDE_VAR_REF_SET(0))
|
||||
self.ad9154.dac_write(AD9154_VCO_CAL,
|
||||
AD9154_SPI_FB_CLOCK_ADV_SET(0x2) |
|
||||
AD9154_SPI_VCO_CAL_COUNT_SET(0x3) |
|
||||
AD9154_SPI_VCO_CAL_ALC_WAIT_SET(0) |
|
||||
AD9154_SPI_VCO_CAL_EN_SET(1))
|
||||
self.ad9154.dac_write(AD9154_CP_LEVEL_DETECT,
|
||||
AD9154_SPI_CP_LEVEL_THRESHOLD_HIGH_SET(0x2) |
|
||||
AD9154_SPI_CP_LEVEL_THRESHOLD_LOW_SET(0x5) |
|
||||
AD9154_SPI_CP_LEVEL_DET_PD_SET(0))
|
||||
self.ad9154.dac_write(AD9154_VCO_VARACTOR_CTRL_0,
|
||||
AD9154_SPI_VCO_VARACTOR_OFFSET_SET(0xe) |
|
||||
AD9154_SPI_VCO_VARACTOR_REF_TCF_SET(0x7))
|
||||
self.ad9154.dac_write(AD9154_VCO_VARACTOR_CTRL_1,
|
||||
AD9154_SPI_VCO_VARACTOR_REF_SET(0x6))
|
||||
# ensure link is txing
|
||||
#self.ad9154.dac_write(AD9154_SERDESPLL_ENABLE_CNTRL,
|
||||
# AD9154_ENABLE_SERDESPLL_SET(1) | AD9154_RECAL_SERDESPLL_SET(1))
|
||||
self.ad9154.dac_write(AD9154_SERDESPLL_ENABLE_CNTRL,
|
||||
AD9154_ENABLE_SERDESPLL_SET(1) | AD9154_RECAL_SERDESPLL_SET(0))
|
||||
while not AD9154_SERDES_PLL_LOCK_RB_GET(self.ad9154.dac_read(AD9154_PLL_STATUS)):
|
||||
pass
|
||||
|
||||
self.ad9154.dac_write(AD9154_EQ_BIAS_REG, AD9154_EQ_BIAS_RESERVED_SET(0x22) |
|
||||
AD9154_EQ_POWER_MODE_SET(1))
|
||||
|
||||
self.ad9154.dac_write(AD9154_GENERAL_JRX_CTRL_1, 1) # subclass 1
|
||||
self.ad9154.dac_write(AD9154_LMFC_DELAY_0, 0)
|
||||
self.ad9154.dac_write(AD9154_LMFC_DELAY_1, 0)
|
||||
self.ad9154.dac_write(AD9154_LMFC_VAR_0, 0x0a) # receive buffer delay
|
||||
self.ad9154.dac_write(AD9154_LMFC_VAR_1, 0x0a)
|
||||
self.ad9154.dac_write(AD9154_SYNC_ERRWINDOW, 0) # +- 1/2 DAC clock
|
||||
self.ad9154.dac_write(AD9154_SYNC_CONTROL,
|
||||
AD9154_SYNCMODE_SET(0x9) | AD9154_SYNCENABLE_SET(0) |
|
||||
AD9154_SYNCARM_SET(0) | AD9154_SYNCCLRSTKY_SET(1) |
|
||||
AD9154_SYNCCLRLAST_SET(1))
|
||||
self.ad9154.dac_write(AD9154_SYNC_CONTROL,
|
||||
AD9154_SYNCMODE_SET(0x9) | AD9154_SYNCENABLE_SET(1) |
|
||||
AD9154_SYNCARM_SET(0) | AD9154_SYNCCLRSTKY_SET(1) |
|
||||
AD9154_SYNCCLRLAST_SET(1))
|
||||
self.ad9154.dac_write(AD9154_SYNC_CONTROL,
|
||||
AD9154_SYNCMODE_SET(0x9) | AD9154_SYNCENABLE_SET(1) |
|
||||
AD9154_SYNCARM_SET(1) | AD9154_SYNCCLRSTKY_SET(0) |
|
||||
AD9154_SYNCCLRLAST_SET(0))
|
||||
self.busywait_us(1000) # ensure at least one sysref edge
|
||||
if not AD9154_SYNC_LOCK_GET(self.ad9154.dac_read(AD9154_SYNC_STATUS)):
|
||||
raise ValueError("no sync lock")
|
||||
self.ad9154.dac_write(AD9154_XBAR_LN_0_1,
|
||||
AD9154_LOGICAL_LANE0_SRC_SET(7) | AD9154_LOGICAL_LANE1_SRC_SET(6))
|
||||
self.ad9154.dac_write(AD9154_XBAR_LN_2_3,
|
||||
AD9154_LOGICAL_LANE2_SRC_SET(5) | AD9154_LOGICAL_LANE3_SRC_SET(4))
|
||||
self.ad9154.dac_write(AD9154_XBAR_LN_4_5,
|
||||
AD9154_LOGICAL_LANE4_SRC_SET(0) | AD9154_LOGICAL_LANE5_SRC_SET(0))
|
||||
self.ad9154.dac_write(AD9154_XBAR_LN_6_7,
|
||||
AD9154_LOGICAL_LANE6_SRC_SET(0) | AD9154_LOGICAL_LANE7_SRC_SET(0))
|
||||
self.ad9154.dac_write(AD9154_JESD_BIT_INVERSE_CTRL, 0x00)
|
||||
self.ad9154.dac_write(AD9154_GENERAL_JRX_CTRL_0,
|
||||
AD9154_LINK_EN_SET(0x1) | AD9154_LINK_PAGE_SET(0) |
|
||||
AD9154_LINK_MODE_SET(0) | AD9154_CHECKSUM_MODE_SET(0))
|
||||
|
||||
@kernel
|
||||
def monitor(self):
|
||||
self.ad9154.dac_write(AD9154_IRQ_STATUS0, 0x00)
|
||||
self.ad9154.dac_write(AD9154_IRQ_STATUS1, 0x00)
|
||||
self.ad9154.dac_write(AD9154_IRQ_STATUS2, 0x00)
|
||||
self.ad9154.dac_write(AD9154_IRQ_STATUS3, 0x00)
|
||||
|
||||
self.ad9154.dac_write(AD9154_IRQEN_STATUSMODE0,
|
||||
AD9154_IRQEN_SMODE_LANEFIFOERR_SET(1) |
|
||||
AD9154_IRQEN_SMODE_SERPLLLOCK_SET(1) |
|
||||
AD9154_IRQEN_SMODE_SERPLLLOST_SET(1) |
|
||||
AD9154_IRQEN_SMODE_DACPLLLOCK_SET(1) |
|
||||
AD9154_IRQEN_SMODE_DACPLLLOST_SET(1))
|
||||
|
||||
self.ad9154.dac_write(AD9154_IRQEN_STATUSMODE1,
|
||||
AD9154_IRQEN_SMODE_PRBS0_SET(1) |
|
||||
AD9154_IRQEN_SMODE_PRBS1_SET(1) |
|
||||
AD9154_IRQEN_SMODE_PRBS2_SET(1) |
|
||||
AD9154_IRQEN_SMODE_PRBS3_SET(1))
|
||||
|
||||
self.ad9154.dac_write(AD9154_IRQEN_STATUSMODE2,
|
||||
AD9154_IRQEN_SMODE_SYNC_TRIP0_SET(1) |
|
||||
AD9154_IRQEN_SMODE_SYNC_WLIM0_SET(1) |
|
||||
AD9154_IRQEN_SMODE_SYNC_ROTATE0_SET(1) |
|
||||
AD9154_IRQEN_SMODE_SYNC_LOCK0_SET(1) |
|
||||
AD9154_IRQEN_SMODE_NCO_ALIGN0_SET(1) |
|
||||
AD9154_IRQEN_SMODE_BLNKDONE0_SET(1) |
|
||||
AD9154_IRQEN_SMODE_PDPERR0_SET(1))
|
||||
|
||||
self.ad9154.dac_write(AD9154_IRQEN_STATUSMODE3,
|
||||
AD9154_IRQEN_SMODE_SYNC_TRIP1_SET(1) |
|
||||
AD9154_IRQEN_SMODE_SYNC_WLIM1_SET(1) |
|
||||
AD9154_IRQEN_SMODE_SYNC_ROTATE1_SET(1) |
|
||||
AD9154_IRQEN_SMODE_SYNC_LOCK1_SET(1) |
|
||||
AD9154_IRQEN_SMODE_NCO_ALIGN1_SET(1) |
|
||||
AD9154_IRQEN_SMODE_BLNKDONE1_SET(1) |
|
||||
AD9154_IRQEN_SMODE_PDPERR1_SET(1))
|
||||
|
||||
self.ad9154.dac_write(AD9154_IRQ_STATUS0, 0x00)
|
||||
self.ad9154.dac_write(AD9154_IRQ_STATUS1, 0x00)
|
||||
self.ad9154.dac_write(AD9154_IRQ_STATUS2, 0x00)
|
||||
self.ad9154.dac_write(AD9154_IRQ_STATUS3, 0x00)
|
@ -14,7 +14,7 @@ class SAWGTest(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.break_realtime()
|
||||
self.core.reset()
|
||||
self.ttl_sma.output()
|
||||
|
||||
while True:
|
||||
|
@ -14,7 +14,7 @@ class SAWGTest(EnvExperiment):
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.core.break_realtime()
|
||||
self.core.reset()
|
||||
self.ttl_sma.output()
|
||||
|
||||
while True:
|
||||
|
@ -1,3 +1,5 @@
|
||||
# TODO: move to firmware
|
||||
|
||||
from artiq.coredevice.ad9154_reg import *
|
||||
from artiq.experiment import *
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
# TODO: move to firmware
|
||||
|
||||
from artiq.coredevice.ad9154_reg import *
|
||||
from artiq.experiment import *
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
# TODO: move to firmware
|
||||
|
||||
from jesd204b.transport import seed_to_data
|
||||
|
||||
from artiq.coredevice.ad9154_reg import *
|
||||
|
@ -1,72 +0,0 @@
|
||||
from artiq.experiment import *
|
||||
from artiq.coredevice.ad9516_reg import *
|
||||
|
||||
|
||||
class StartupKernel(EnvExperiment):
|
||||
def build(self):
|
||||
self.setattr_device("core")
|
||||
self.setattr_device("led")
|
||||
self.setattr_device("ad9154")
|
||||
|
||||
@kernel
|
||||
def run(self):
|
||||
self.ad9154.jesd_enable(0)
|
||||
self.ad9154.init()
|
||||
self.clock_setup()
|
||||
|
||||
@kernel
|
||||
def clock_setup(self):
|
||||
# reset
|
||||
self.ad9154.clock_write(AD9516_SERIAL_PORT_CONFIGURATION,
|
||||
AD9516_SOFT_RESET | AD9516_SOFT_RESET_MIRRORED |
|
||||
AD9516_LONG_INSTRUCTION | AD9516_LONG_INSTRUCTION_MIRRORED |
|
||||
AD9516_SDO_ACTIVE | AD9516_SDO_ACTIVE_MIRRORED)
|
||||
self.ad9154.clock_write(AD9516_SERIAL_PORT_CONFIGURATION,
|
||||
AD9516_LONG_INSTRUCTION | AD9516_LONG_INSTRUCTION_MIRRORED |
|
||||
AD9516_SDO_ACTIVE | AD9516_SDO_ACTIVE_MIRRORED)
|
||||
if self.ad9154.clock_read(AD9516_PART_ID) != 0x41:
|
||||
raise ValueError("AD9516 not found")
|
||||
|
||||
# use clk input, dclk=clk/2
|
||||
self.ad9154.clock_write(AD9516_PFD_AND_CHARGE_PUMP, 1*AD9516_PLL_POWER_DOWN |
|
||||
0*AD9516_CHARGE_PUMP_MODE)
|
||||
self.ad9154.clock_write(AD9516_VCO_DIVIDER, 0)
|
||||
self.ad9154.clock_write(AD9516_INPUT_CLKS, 0*AD9516_SELECT_VCO_OR_CLK |
|
||||
0*AD9516_BYPASS_VCO_DIVIDER)
|
||||
|
||||
self.ad9154.clock_write(AD9516_OUT0, 2*AD9516_OUT0_POWER_DOWN)
|
||||
self.ad9154.clock_write(AD9516_OUT2, 2*AD9516_OUT2_POWER_DOWN)
|
||||
self.ad9154.clock_write(AD9516_OUT3, 2*AD9516_OUT3_POWER_DOWN)
|
||||
self.ad9154.clock_write(AD9516_OUT4, 2*AD9516_OUT4_POWER_DOWN)
|
||||
self.ad9154.clock_write(AD9516_OUT5, 2*AD9516_OUT5_POWER_DOWN)
|
||||
self.ad9154.clock_write(AD9516_OUT8, 1*AD9516_OUT8_POWER_DOWN)
|
||||
|
||||
# DAC deviceclk, clk/1
|
||||
self.ad9154.clock_write(AD9516_DIVIDER_0_2, AD9516_DIVIDER_0_DIRECT_TO_OUTPUT)
|
||||
self.ad9154.clock_write(AD9516_OUT1, 0*AD9516_OUT1_POWER_DOWN |
|
||||
2*AD9516_OUT1_LVPECLDIFFERENTIAL_VOLTAGE)
|
||||
|
||||
# FPGA deviceclk, dclk/1
|
||||
self.ad9154.clock_write(AD9516_DIVIDER_4_3, 0*AD9516_DIVIDER_4_NOSYNC |
|
||||
1*AD9516_DIVIDER_4_BYPASS_1 | 1*AD9516_DIVIDER_4_BYPASS_2)
|
||||
self.ad9154.clock_write(AD9516_DIVIDER_4_4, 0*AD9516_DIVIDER_4_DCCOFF)
|
||||
self.ad9154.clock_write(AD9516_OUT9, 1*AD9516_OUT9_LVDS_OUTPUT_CURRENT |
|
||||
2*AD9516_OUT9_LVDS_CMOS_OUTPUT_POLARITY |
|
||||
0*AD9516_OUT9_SELECT_LVDS_CMOS)
|
||||
|
||||
# sysref f_data*S/(K*F), dclk/16
|
||||
self.ad9154.clock_write(AD9516_DIVIDER_3_0, (16//2-1)*AD9516_DIVIDER_3_HIGH_CYCLES_1 |
|
||||
(16//2-1)*AD9516_DIVIDER_3_LOW_CYCLES_1)
|
||||
self.ad9154.clock_write(AD9516_DIVIDER_3_1, 0*AD9516_DIVIDER_3_PHASE_OFFSET_1 |
|
||||
0*AD9516_DIVIDER_3_PHASE_OFFSET_2)
|
||||
self.ad9154.clock_write(AD9516_DIVIDER_3_3, 0*AD9516_DIVIDER_3_NOSYNC |
|
||||
0*AD9516_DIVIDER_3_BYPASS_1 | 1*AD9516_DIVIDER_3_BYPASS_2)
|
||||
self.ad9154.clock_write(AD9516_DIVIDER_3_4, 0*AD9516_DIVIDER_3_DCCOFF)
|
||||
self.ad9154.clock_write(AD9516_OUT6, 1*AD9516_OUT6_LVDS_OUTPUT_CURRENT |
|
||||
2*AD9516_OUT6_LVDS_CMOS_OUTPUT_POLARITY |
|
||||
0*AD9516_OUT6_SELECT_LVDS_CMOS)
|
||||
self.ad9154.clock_write(AD9516_OUT7, 1*AD9516_OUT7_LVDS_OUTPUT_CURRENT |
|
||||
2*AD9516_OUT7_LVDS_CMOS_OUTPUT_POLARITY |
|
||||
0*AD9516_OUT7_SELECT_LVDS_CMOS)
|
||||
|
||||
self.ad9154.clock_write(AD9516_UPDATE_ALL_REGISTERS, 1)
|
@ -35,6 +35,12 @@ fn read(addr: u16) -> u8 {
|
||||
}
|
||||
}
|
||||
|
||||
fn jesd_reset(rst: bool) {
|
||||
unsafe {
|
||||
csr::ad9154::jesd_jreset_write(if rst {1} else {0})
|
||||
}
|
||||
}
|
||||
|
||||
fn jesd_enable(en: bool) {
|
||||
unsafe {
|
||||
csr::ad9154::jesd_control_enable_write(if en {1} else {0})
|
||||
@ -454,6 +460,10 @@ fn cfg() -> Result<(), &'static str> {
|
||||
pub fn init() -> Result<(), &'static str> {
|
||||
spi_setup();
|
||||
|
||||
// Release the JESD clock domain reset late, as we need to
|
||||
// set up clock chips before.
|
||||
jesd_reset(false);
|
||||
|
||||
for i in 0..99 {
|
||||
let outcome = cfg();
|
||||
match outcome {
|
||||
|
@ -11,6 +11,16 @@ include!(concat!(env!("BUILDINC_DIRECTORY"), "/generated/csr.rs"));
|
||||
pub mod spr;
|
||||
pub mod irq;
|
||||
pub mod clock;
|
||||
// XXX #[cfg(has_ad9516)]
|
||||
#[allow(dead_code)]
|
||||
mod ad9516_reg;
|
||||
// XXX #[cfg(has_ad9516)]
|
||||
pub mod ad9516;
|
||||
// XXX #[cfg(has_converter_spi)]
|
||||
#[allow(dead_code)]
|
||||
mod ad9154_reg;
|
||||
// XXX #[cfg(has_converter_spi)]
|
||||
pub mod ad9154;
|
||||
|
||||
extern {
|
||||
pub fn flush_cpu_dcache();
|
||||
|
@ -1,75 +0,0 @@
|
||||
use board::csr;
|
||||
|
||||
pub extern fn init() {
|
||||
unsafe {
|
||||
csr::ad9154::spi_offline_write(1);
|
||||
csr::ad9154::spi_cs_polarity_write(0);
|
||||
csr::ad9154::spi_clk_polarity_write(0);
|
||||
csr::ad9154::spi_clk_phase_write(0);
|
||||
csr::ad9154::spi_lsb_first_write(0);
|
||||
csr::ad9154::spi_half_duplex_write(0);
|
||||
csr::ad9154::spi_clk_div_write_write(16);
|
||||
csr::ad9154::spi_clk_div_read_write(16);
|
||||
csr::ad9154::spi_xfer_len_write_write(24);
|
||||
csr::ad9154::spi_xfer_len_read_write(0);
|
||||
csr::ad9154::spi_cs_write(csr::CONFIG_AD9154_DAC_CS);
|
||||
csr::ad9154::spi_offline_write(0);
|
||||
}
|
||||
}
|
||||
|
||||
const AD9_READ: u16 = 1 << 15;
|
||||
|
||||
pub extern fn dac_write(addr: u16, data: u8) {
|
||||
unsafe {
|
||||
csr::ad9154::spi_data_write_write(
|
||||
((addr as u32) << 16) | ((data as u32) << 8));
|
||||
while csr::ad9154::spi_pending_read() != 0 {}
|
||||
while csr::ad9154::spi_active_read() != 0 {}
|
||||
}
|
||||
}
|
||||
|
||||
pub extern fn dac_read(addr: u16) -> u8 {
|
||||
unsafe {
|
||||
dac_write(AD9_READ | addr, 0);
|
||||
csr::ad9154::spi_data_read_read() as u8
|
||||
}
|
||||
}
|
||||
|
||||
pub extern fn clk_write(addr: u16, data: u8) {
|
||||
unsafe {
|
||||
csr::ad9154::spi_cs_write(csr::CONFIG_AD9154_CLK_CS);
|
||||
dac_write(addr, data);
|
||||
csr::ad9154::spi_cs_write(csr::CONFIG_AD9154_DAC_CS);
|
||||
}
|
||||
}
|
||||
|
||||
pub extern fn clk_read(addr: u16) -> u8 {
|
||||
unsafe {
|
||||
clk_write(AD9_READ | addr, 0);
|
||||
csr::ad9154::spi_data_read_read() as u8
|
||||
}
|
||||
}
|
||||
|
||||
pub extern fn jesd_enable(en: u32) {
|
||||
unsafe {
|
||||
csr::ad9154::jesd_control_enable_write(en);
|
||||
}
|
||||
}
|
||||
|
||||
pub extern fn jesd_ready() {
|
||||
unsafe {
|
||||
csr::ad9154::jesd_control_ready_read();
|
||||
}
|
||||
}
|
||||
|
||||
pub extern fn jesd_prbs(p: u32) {
|
||||
unsafe {
|
||||
csr::ad9154::jesd_control_prbs_config_write(p);
|
||||
}
|
||||
}
|
||||
|
||||
pub extern fn jesd_stpl(en: u32) {
|
||||
unsafe {
|
||||
csr::ad9154::jesd_control_stpl_enable_write(en);
|
||||
}
|
||||
}
|
@ -116,23 +116,4 @@ static mut API: &'static [(&'static str, *const ())] = &[
|
||||
api!(i2c_write = ::i2c::write),
|
||||
#[cfg(has_i2c)]
|
||||
api!(i2c_read = ::i2c::read),
|
||||
|
||||
#[cfg(has_ad9154)]
|
||||
api!(ad9154_init = ::ad9154::init),
|
||||
#[cfg(has_ad9154)]
|
||||
api!(ad9154_write = ::ad9154::dac_write),
|
||||
#[cfg(has_ad9154)]
|
||||
api!(ad9154_read = ::ad9154::dac_read),
|
||||
#[cfg(has_ad9154)]
|
||||
api!(ad9516_write = ::ad9154::clk_write),
|
||||
#[cfg(has_ad9154)]
|
||||
api!(ad9516_read = ::ad9154::clk_read),
|
||||
#[cfg(has_ad9154)]
|
||||
api!(ad9154_jesd_enable = ::ad9154::jesd_enable),
|
||||
#[cfg(has_ad9154)]
|
||||
api!(ad9154_jesd_ready = ::ad9154::jesd_ready),
|
||||
#[cfg(has_ad9154)]
|
||||
api!(ad9154_jesd_prbs = ::ad9154::jesd_prbs),
|
||||
#[cfg(has_ad9154)]
|
||||
api!(ad9154_jesd_stpl = ::ad9154::jesd_stpl),
|
||||
];
|
||||
|
@ -50,8 +50,6 @@ macro_rules! artiq_raise {
|
||||
mod rtio;
|
||||
#[cfg(has_i2c)]
|
||||
mod i2c;
|
||||
#[cfg(has_ad9154)]
|
||||
mod ad9154;
|
||||
|
||||
use core::{mem, ptr, slice, str};
|
||||
use std::io::Cursor;
|
||||
|
@ -118,6 +118,10 @@ pub unsafe extern fn rust_main() {
|
||||
}
|
||||
info!("continuing boot");
|
||||
|
||||
#[cfg(has_ad9516)]
|
||||
board::ad9516::init().unwrap();
|
||||
#[cfg(has_converter_spi)]
|
||||
board::ad9154::init().unwrap();
|
||||
network_init();
|
||||
|
||||
let mut scheduler = sched::Scheduler::new();
|
||||
|
@ -37,6 +37,13 @@ class _PhaserCRG(Module, AutoCSR):
|
||||
self.clock_domains.cd_rtio = ClockDomain()
|
||||
self.clock_domains.cd_rtiox4 = ClockDomain(reset_less=True)
|
||||
|
||||
external_clk = Signal()
|
||||
user_sma_clock = platform.request("user_sma_clock")
|
||||
platform.add_period_constraint(user_sma_clock.p, 20/3)
|
||||
self.specials += Instance("IBUFDS",
|
||||
i_I=user_sma_clock.p, i_IB=user_sma_clock.n,
|
||||
o_O=external_clk)
|
||||
|
||||
pll_locked = Signal()
|
||||
rtio_clk = Signal()
|
||||
rtiox4_clk = Signal()
|
||||
@ -46,7 +53,7 @@ class _PhaserCRG(Module, AutoCSR):
|
||||
|
||||
p_REF_JITTER1=0.01, p_REF_JITTER2=0.01,
|
||||
p_CLKIN1_PERIOD=20/3, p_CLKIN2_PERIOD=20/3,
|
||||
i_CLKIN1=0, i_CLKIN2=refclk,
|
||||
i_CLKIN1=refclk, i_CLKIN2=external_clk,
|
||||
# Warning: CLKINSEL=0 means CLKIN2 is selected
|
||||
i_CLKINSEL=~self._clock_sel.storage,
|
||||
|
||||
@ -58,13 +65,11 @@ class _PhaserCRG(Module, AutoCSR):
|
||||
o_CLKFBOUT=rtio_clk,
|
||||
|
||||
p_CLKOUT0_DIVIDE=2, p_CLKOUT0_PHASE=0.0,
|
||||
o_CLKOUT0=rtiox4_clk,
|
||||
),
|
||||
o_CLKOUT0=rtiox4_clk),
|
||||
Instance("BUFG", i_I=rtio_clk, o_O=self.cd_rtio.clk),
|
||||
Instance("BUFG", i_I=rtiox4_clk, o_O=self.cd_rtiox4.clk),
|
||||
AsyncResetSynchronizer(self.cd_rtio, ~pll_locked),
|
||||
MultiReg(pll_locked | ~self._clock_sel.storage,
|
||||
self._pll_locked.status)
|
||||
MultiReg(pll_locked, self._pll_locked.status)
|
||||
]
|
||||
self.cd_rtio.clk.attr.add("keep")
|
||||
platform.add_period_constraint(self.cd_rtio.clk, 20/3)
|
||||
@ -72,6 +77,9 @@ class _PhaserCRG(Module, AutoCSR):
|
||||
|
||||
class AD9154JESD(Module, AutoCSR):
|
||||
def __init__(self, platform):
|
||||
self.jreset = CSRStorage(reset=1)
|
||||
self.jsync = CSRStatus()
|
||||
|
||||
ps = JESD204BPhysicalSettings(l=4, m=4, n=16, np=16)
|
||||
ts = JESD204BTransportSettings(f=2, s=1, k=16, cs=1)
|
||||
settings = JESD204BSettings(ps, ts, did=0x5a, bid=0x5)
|
||||
@ -79,11 +87,6 @@ class AD9154JESD(Module, AutoCSR):
|
||||
refclk_freq = 150e6
|
||||
fabric_freq = 150*1000*1000
|
||||
|
||||
sync_pads = platform.request("ad9154_sync")
|
||||
self.jsync = Signal()
|
||||
self.specials += DifferentialInput(
|
||||
sync_pads.p, sync_pads.n, self.jsync)
|
||||
|
||||
refclk = Signal()
|
||||
self.clock_domains.cd_jesd = ClockDomain()
|
||||
refclk_pads = platform.request("ad9154_refclk")
|
||||
@ -92,7 +95,7 @@ class AD9154JESD(Module, AutoCSR):
|
||||
Instance("IBUFDS_GTE2", i_CEB=0,
|
||||
i_I=refclk_pads.p, i_IB=refclk_pads.n, o_O=refclk),
|
||||
Instance("BUFG", i_I=refclk, o_O=self.cd_jesd.clk),
|
||||
AsyncResetSynchronizer(self.cd_jesd, ResetSignal("rio_phy")),
|
||||
AsyncResetSynchronizer(self.cd_jesd, self.jreset.storage),
|
||||
]
|
||||
self.cd_jesd.clk.attr.add("keep")
|
||||
platform.add_period_constraint(self.cd_jesd.clk, 1e9/refclk_freq)
|
||||
@ -113,11 +116,18 @@ class AD9154JESD(Module, AutoCSR):
|
||||
converter_data_width=32))
|
||||
self.submodules.control = to_jesd(JESD204BCoreTXControl(self.core))
|
||||
|
||||
sync_pads = platform.request("ad9154_sync")
|
||||
jsync = Signal()
|
||||
self.specials += [
|
||||
DifferentialInput(sync_pads.p, sync_pads.n, jsync),
|
||||
MultiReg(jsync, self.jsync.status)
|
||||
]
|
||||
|
||||
self.comb += [
|
||||
platform.request("ad9154_txen", 0).eq(1),
|
||||
platform.request("ad9154_txen", 1).eq(1),
|
||||
self.core.start.eq(self.jsync),
|
||||
platform.request("user_led", 3).eq(self.jsync),
|
||||
self.core.start.eq(jsync),
|
||||
platform.request("user_led", 3).eq(jsync),
|
||||
]
|
||||
|
||||
# blinking leds for transceiver reset status
|
||||
@ -135,11 +145,6 @@ class AD9154JESD(Module, AutoCSR):
|
||||
|
||||
class AD9154(Module, AutoCSR):
|
||||
def __init__(self, platform):
|
||||
ad9154_spi = platform.request("ad9154_spi")
|
||||
self.comb += ad9154_spi.en.eq(1)
|
||||
|
||||
self.submodules.spi = spi_csr.SPIMaster(ad9154_spi)
|
||||
|
||||
self.submodules.jesd = AD9154JESD(platform)
|
||||
|
||||
self.sawgs = [sawg.Channel(width=16, parallelism=2) for i in range(4)]
|
||||
@ -186,10 +191,16 @@ class Phaser(MiniSoC, AMPSoC):
|
||||
self.register_kernel_cpu_csrdevice("i2c")
|
||||
self.config["I2C_BUS_COUNT"] = 1
|
||||
|
||||
ad9154_spi = platform.request("ad9154_spi")
|
||||
self.comb += ad9154_spi.en.eq(1)
|
||||
self.submodules.converter_spi = spi_csr.SPIMaster(ad9154_spi)
|
||||
self.csr_devices.append("converter_spi")
|
||||
self.config["CONVERTER_SPI_DAC_CS"] = 0
|
||||
self.config["CONVERTER_SPI_CLK_CS"] = 1
|
||||
self.config["HAS_AD9516"] = None
|
||||
|
||||
self.submodules.ad9154 = AD9154(platform)
|
||||
self.register_kernel_cpu_csrdevice("ad9154")
|
||||
self.config["AD9154_DAC_CS"] = 1 << 0
|
||||
self.config["AD9154_CLK_CS"] = 1 << 1
|
||||
self.csr_devices.append("ad9154")
|
||||
|
||||
rtio_channels = []
|
||||
|
||||
@ -208,11 +219,6 @@ class Phaser(MiniSoC, AMPSoC):
|
||||
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=32,
|
||||
ofifo_depth=2))
|
||||
|
||||
phy = ttl_simple.Input(self.ad9154.jesd.jsync)
|
||||
self.submodules += phy
|
||||
rtio_channels.append(rtio.Channel.from_phy(phy, ififo_depth=32,
|
||||
ofifo_depth=2))
|
||||
|
||||
self.config["RTIO_REGULAR_TTL_COUNT"] = len(rtio_channels)
|
||||
|
||||
self.config["RTIO_FIRST_SAWG_CHANNEL"] = len(rtio_channels)
|
||||
|
Loading…
Reference in New Issue
Block a user