Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: f754d2c11776
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1e4bccae20f7
Choose a head ref
  • 3 commits
  • 2 files changed
  • 1 contributor

Commits on Mar 1, 2016

  1. Copy the full SHA
    d973eb8 View commit details
  2. Copy the full SHA
    162ecdd View commit details
  3. ad53xx: add

    jordens committed Mar 1, 2016
    Copy the full SHA
    1e4bcca View commit details
Showing with 81 additions and 7 deletions.
  1. +71 −0 artiq/coredevice/ad53xx.py
  2. +10 −7 artiq/coredevice/spi.py
71 changes: 71 additions & 0 deletions artiq/coredevice/ad53xx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from artiq.language.core import (kernel, portable, delay, delay_mu, int)
from artiq.language.units import ns
from artiq.coredevice import spi


_AD53xx_SPI_CONFIG = (0*spi.SPI_OFFLINE | 0*spi.SPI_CS_POLARITY |
0*spi.SPI_CLK_POLARITY | 0*spi.SPI_CLK_PHASE |
0*spi.SPI_LSB_FIRST | 0*spi.SPI_HALF_DUPLEX)

_AD53xx_MODE_WRITE_X1 = 3 << 22
_AD53xx_MODE_WRITE_C = 2 << 22
_AD53xx_MODE_WRITE_M = 1 << 22
_AD53xx_MODE_SPECIAL = 0 << 22

_AD53xx_GROUP = portable(lambda g: ((g + 1) << 19))
_AD53xx_GROUP_ALL = 0 << 19
_AD53xx_GROUP_01234 = 6 << 19
_AD53xx_GROUP_1234 = 7 << 19
_AD53xx_CHANNEL_ALL = 0 << 16
_AD53xx_CHANNEL = portable(lambda g: g << 16)

_AD53xx_SPECIAL_NOP = 0 << 16
_AD53xx_SPECIAL_CONTROL = 1 << 16
_AD53xx_SPECIAL_OFS0 = 2 << 16
_AD53xx_SPECIAL_OFS1 = 3 << 16
_AD53xx_SPECIAL_AB_SELECT = portable(lambda i: (i + 6) << 16)
_AD53xx_SPECIAL_AB_SELECT_ALL = 11 << 16

_AD53xx_READ_X1A = portable(lambda ch: (0x00 | (ch + 8)) << 7)
_AD53xx_READ_X1B = portable(lambda ch: (0x40 | (ch + 8)) << 7)
_AD53xx_READ_C = portable(lambda ch: (0x80 | (ch + 8)) << 7)
_AD53xx_READ_M = portable(lambda ch: (0xc0 | (ch + 8)) << 7)
_AD53xx_READ_CONTROL = 0x101 << 7
_AD53xx_READ_OFS0 = 0x102 << 7
_AD53xx_READ_OFS1 = 0x103 << 7
_AD53xx_READ_AB_SELECT = portable(lambda i: (0x100 + (i + 6)) << 7)


class AD53xx:
def __init__(self, dmgr, spi_bus, ldac=None,
chip_select=0, write_div=4, read_div=6):
self.core = dmgr.get("core")
self.bus = dmgr.get(spi_bus)
# if ldac is not None:
ldac = dmgr.get(ldac)
self.ldac = ldac
self.chip_select = chip_select
self.write_div = write_div
self.read_div = read_div

@kernel
def bus_setup(self):
self.bus.set_config_mu(_AD53xx_SPI_CONFIG, self.write_div,
self.read_div)
self.bus.set_xfer(self.chip_select, 24, 0)

@kernel
def _channel_address(self, channel=0):
return int((channel + 8) << 16)

@kernel
def write_x1(self, channel=0, value=0):
ch = self._channel_address(channel)
self.bus.write(_AD53xx_MODE_WRITE_X1 | ch | value)
delay_mu(int(self.bus.xfer_period_mu + self.bus.write_period_mu))

@kernel
def load(self):
self.ldac.off()
delay(20*ns)
self.ldac.on()
17 changes: 10 additions & 7 deletions artiq/coredevice/spi.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from artiq.language.core import (kernel, seconds_to_mu, now_mu,
from artiq.language.core import (kernel, portable, seconds_to_mu, now_mu,
delay_mu, int)
from artiq.language.units import MHz
from artiq.coredevice.rtio import rtio_output, rtio_input_data
@@ -57,6 +57,10 @@ def __init__(self, dmgr, ref_period, channel):
# To chain transfers together, new data must be written before
# pending transfer's read data becomes available.

@portable
def frequency_to_div(self, f):
return int(1/(f*self.ref_period)) + 1

@kernel
def set_config(self, flags=0, write_freq=20*MHz, read_freq=20*MHz):
"""Set the configuration register.
@@ -105,9 +109,8 @@ def set_config(self, flags=0, write_freq=20*MHz, read_freq=20*MHz):
:param write_freq: Desired SPI clock frequency during write bits.
:param read_freq: Desired SPI clock frequency during read bits.
"""
write_div = round(1/(write_freq*self.ref_period))
read_div = round(1/(read_freq*self.ref_period))
self.set_config_mu(flags, write_div, read_div)
self.set_config_mu(flags, self.frequency_to_div(write_freq),
self.frequency_to_div(read_freq))

@kernel
def set_config_mu(self, flags=0, write_div=6, read_div=6):
@@ -174,7 +177,7 @@ def set_xfer(self, chip_select=0, write_length=0, read_length=0):
delay_mu(3*self.ref_period_mu)

@kernel
def write(self, data):
def write(self, data=0):
"""Write data to data register.
* The ``data`` register and the shift register are 32 bits wide.
@@ -203,7 +206,7 @@ def write(self, data):

@kernel
def read_async(self):
"""Trigger an asynchronous read from the data register.
"""Trigger an asynchronous read from the ``data`` register.
Reads always finish in two cycles.
@@ -218,7 +221,7 @@ def read_async(self):

@kernel
def input_async(self):
"""Retrieves data written asynchronously.
"""Retrieves data read asynchronously from the ``data`` register.
:meth:`input_async` must match a preeeding :meth:`read_async`.
"""