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: 200cddc34685
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: e834a8834028
Choose a head ref
  • 3 commits
  • 3 files changed
  • 1 contributor

Commits on Mar 4, 2016

  1. Copy the full SHA
    4ae3ca5 View commit details
  2. Copy the full SHA
    710717c View commit details
  3. ad5360: style

    jordens committed Mar 4, 2016
    Copy the full SHA
    e834a88 View commit details
Showing with 49 additions and 27 deletions.
  1. +34 −18 artiq/coredevice/ad5360.py
  2. +6 −7 artiq/coredevice/spi.py
  3. +9 −2 examples/master/device_db.pyon
52 changes: 34 additions & 18 deletions artiq/coredevice/ad5360.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from artiq.language.core import kernel, portable, delay
from artiq.language.units import ns
from artiq.language.core import kernel, portable, delay_mu
from artiq.coredevice import spi

# Designed from the data sheets and somewhat after the linux kernel
# iio driver.

_AD5360_SPI_CONFIG = (0*spi.SPI_OFFLINE | 0*spi.SPI_CS_POLARITY |
0*spi.SPI_CLK_POLARITY | 1*spi.SPI_CLK_PHASE |
@@ -21,7 +22,7 @@ def _AD5360_WRITE_CHANNEL(c):
_AD5360_SPECIAL_CONTROL = 1 << 16
_AD5360_SPECIAL_OFS0 = 2 << 16
_AD5360_SPECIAL_OFS1 = 3 << 16
_AD5360_SPECIAL_READ = 3 << 16
_AD5360_SPECIAL_READ = 5 << 16


@portable
@@ -43,11 +44,11 @@ class AD5360:
multi-channel Digital to Analog Converters
"""

def __init__(self, dmgr, spi_bus, ldac=None, chip_select=0):
def __init__(self, dmgr, spi_device, ldac_device=None, chip_select=1):
self.core = dmgr.get("core")
self.bus = dmgr.get(spi_bus)
if ldac is not None:
ldac = dmgr.get(ldac)
self.bus = dmgr.get(spi_device)
if ldac_device is not None:
ldac = dmgr.get(ldac_device)
self.ldac = ldac
self.chip_select = chip_select

@@ -58,38 +59,53 @@ def setup_bus(self, write_div=4, read_div=7):
self.bus.set_config_mu(_AD5360_SPI_CONFIG, write_div, read_div)
self.bus.set_xfer(self.chip_select, 24, 0)

@kernel
def write(self, data):
self.bus.write(data << 8)
delay_mu(self.bus.ref_period_mu) # get to 20ns min cs high

@kernel
def write_offsets(self, value=0x1fff):
value &= 0x3fff
self.bus.write((_AD5360_CMD_SPECIAL | _AD5360_SPECIAL_OFS0 | value
) << 8)
self.bus.write((_AD5360_CMD_SPECIAL | _AD5360_SPECIAL_OFS1 | value
) << 8)
self.write(_AD5360_CMD_SPECIAL | _AD5360_SPECIAL_OFS0 | value)
self.write(_AD5360_CMD_SPECIAL | _AD5360_SPECIAL_OFS1 | value)

@kernel
def write_channel(self, channel=0, value=0, op=_AD5360_CMD_DATA):
channel &= 0x3f
value &= 0xffff
self.bus.write((op | _AD5360_WRITE_CHANNEL(channel) | value) << 8)
self.write(op | _AD5360_WRITE_CHANNEL(channel) | value)

@kernel
def write_channels(self, values, first=0, op=_AD5360_CMD_DATA):
def write_channels(self, values, op=_AD5360_CMD_DATA):
for i in range(len(values)):
self.write_channel(i + first, values[i], op)
self.write_channel(i, values[i], op)

@kernel
def read_channel_sync(self, channel=0, op=_AD5360_READ_X1A):
channel &= 0x3f
self.bus.write((_AD5360_CMD_SPECIAL | _AD5360_SPECIAL_READ | op |
_AD5360_READ_CHANNEL(channel)) << 8)
self.write(_AD5360_CMD_SPECIAL | _AD5360_SPECIAL_READ | op |
_AD5360_READ_CHANNEL(channel))
self.bus.set_xfer(self.chip_select, 0, 24)
self.bus.write((_AD5360_CMD_SPECIAL | _AD5360_SPECIAL_NOP) << 8)
self.write(_AD5360_CMD_SPECIAL | _AD5360_SPECIAL_NOP)
self.bus.read_async()
self.bus.set_xfer(self.chip_select, 24, 0)
return self.bus.input_async() & 0xffff

@kernel
def load(self):
self.ldac.off()
delay(24*ns)
delay_mu(3*self.bus.ref_period_mu)
self.ldac.on()

@kernel
def set(self, values, op=_AD5360_CMD_DATA):
# write() compensation
delay_mu(-len(values)*(self.bus.xfer_period_mu +
self.bus.write_period_mu +
self.bus.ref_period_mu) -
3*self.bus.ref_period_mu) # latency alignment
self.write_channels(values, op)
delay_mu(3*self.bus.ref_period_mu) # latency alignment
self.load()
delay_mu(-3*self.bus.ref_period_mu) # load() compensation
13 changes: 6 additions & 7 deletions artiq/coredevice/spi.py
Original file line number Diff line number Diff line change
@@ -38,17 +38,16 @@ class SPIMaster:
* If desired, :meth:`write` ``data`` queuing the next
(possibly chained) transfer.
:param ref_period: clock period of the SPI core.
:param channel: RTIO channel number of the SPI bus to control.
"""
def __init__(self, dmgr, ref_period, channel):
def __init__(self, dmgr, channel):
self.core = dmgr.get("core")
self.ref_period = ref_period
self.ref_period_mu = int(seconds_to_mu(ref_period, self.core))
self.ref_period_mu = seconds_to_mu(self.core.coarse_ref_period,
self.core)
self.channel = channel
self.write_period_mu = int(0)
self.read_period_mu = int(0)
self.xfer_period_mu = int(0)
self.write_period_mu = int(0, 64)
self.read_period_mu = int(0, 64)
self.xfer_period_mu = int(0, 64)
# A full transfer takes write_period_mu + xfer_period_mu.
# Chained transfers can happen every xfer_period_mu.
# The second transfer of a chain can be written 2*ref_period_mu
11 changes: 9 additions & 2 deletions examples/master/device_db.pyon
Original file line number Diff line number Diff line change
@@ -81,7 +81,7 @@
"arguments": {"channel": 19}
},

"ams101_ldac": {
"ttl_ams101_ldac": {
"type": "local",
"module": "artiq.coredevice.ttl",
"class": "TTLOut",
@@ -94,7 +94,7 @@
"arguments": {"channel": 21}
},

"ams101_spi": {
"spi_ams101": {
"type": "local",
"module": "artiq.coredevice.spi",
"class": "SPIMaster",
@@ -108,6 +108,13 @@
"arguments": {"channel": 23}
},

"dac0": {
"type": "local",
"module": "artiq.coredevice.ad5360",
"class": "AD5360",
"arguments": {"spi_device": "spi0", "ldac_device": "ttl0"}
},

"dds_bus": {
"type": "local",
"module": "artiq.coredevice.dds",