forked from M-Labs/artiq
spi/ad5360: refactor, small fixes
This commit is contained in:
parent
200cddc346
commit
4ae3ca5f23
|
@ -1,7 +1,8 @@
|
||||||
from artiq.language.core import kernel, portable, delay
|
from artiq.language.core import kernel, portable, delay_mu
|
||||||
from artiq.language.units import ns
|
|
||||||
from artiq.coredevice import spi
|
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 |
|
_AD5360_SPI_CONFIG = (0*spi.SPI_OFFLINE | 0*spi.SPI_CS_POLARITY |
|
||||||
0*spi.SPI_CLK_POLARITY | 1*spi.SPI_CLK_PHASE |
|
0*spi.SPI_CLK_POLARITY | 1*spi.SPI_CLK_PHASE |
|
||||||
|
@ -21,7 +22,7 @@ _AD5360_SPECIAL_NOP = 0 << 16
|
||||||
_AD5360_SPECIAL_CONTROL = 1 << 16
|
_AD5360_SPECIAL_CONTROL = 1 << 16
|
||||||
_AD5360_SPECIAL_OFS0 = 2 << 16
|
_AD5360_SPECIAL_OFS0 = 2 << 16
|
||||||
_AD5360_SPECIAL_OFS1 = 3 << 16
|
_AD5360_SPECIAL_OFS1 = 3 << 16
|
||||||
_AD5360_SPECIAL_READ = 3 << 16
|
_AD5360_SPECIAL_READ = 5 << 16
|
||||||
|
|
||||||
|
|
||||||
@portable
|
@portable
|
||||||
|
@ -43,11 +44,12 @@ class AD5360:
|
||||||
multi-channel Digital to Analog Converters
|
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.core = dmgr.get("core")
|
||||||
self.bus = dmgr.get(spi_bus)
|
self.bus = dmgr.get(spi_device)
|
||||||
if ldac is not None:
|
if ldac_device is not None:
|
||||||
ldac = dmgr.get(ldac)
|
ldac = dmgr.get(ldac_device)
|
||||||
self.ldac = ldac
|
self.ldac = ldac
|
||||||
self.chip_select = chip_select
|
self.chip_select = chip_select
|
||||||
|
|
||||||
|
@ -58,32 +60,35 @@ class AD5360:
|
||||||
self.bus.set_config_mu(_AD5360_SPI_CONFIG, write_div, read_div)
|
self.bus.set_config_mu(_AD5360_SPI_CONFIG, write_div, read_div)
|
||||||
self.bus.set_xfer(self.chip_select, 24, 0)
|
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
|
@kernel
|
||||||
def write_offsets(self, value=0x1fff):
|
def write_offsets(self, value=0x1fff):
|
||||||
value &= 0x3fff
|
value &= 0x3fff
|
||||||
self.bus.write((_AD5360_CMD_SPECIAL | _AD5360_SPECIAL_OFS0 | value
|
self.write(_AD5360_CMD_SPECIAL | _AD5360_SPECIAL_OFS0 | value)
|
||||||
) << 8)
|
self.write(_AD5360_CMD_SPECIAL | _AD5360_SPECIAL_OFS1 | value)
|
||||||
self.bus.write((_AD5360_CMD_SPECIAL | _AD5360_SPECIAL_OFS1 | value
|
|
||||||
) << 8)
|
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def write_channel(self, channel=0, value=0, op=_AD5360_CMD_DATA):
|
def write_channel(self, channel=0, value=0, op=_AD5360_CMD_DATA):
|
||||||
channel &= 0x3f
|
channel &= 0x3f
|
||||||
value &= 0xffff
|
value &= 0xffff
|
||||||
self.bus.write((op | _AD5360_WRITE_CHANNEL(channel) | value) << 8)
|
self.write(op | _AD5360_WRITE_CHANNEL(channel) | value)
|
||||||
|
|
||||||
@kernel
|
@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)):
|
for i in range(len(values)):
|
||||||
self.write_channel(i + first, values[i], op)
|
self.write_channel(i, values[i], op)
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def read_channel_sync(self, channel=0, op=_AD5360_READ_X1A):
|
def read_channel_sync(self, channel=0, op=_AD5360_READ_X1A):
|
||||||
channel &= 0x3f
|
channel &= 0x3f
|
||||||
self.bus.write((_AD5360_CMD_SPECIAL | _AD5360_SPECIAL_READ | op |
|
self.write(_AD5360_CMD_SPECIAL | _AD5360_SPECIAL_READ | op |
|
||||||
_AD5360_READ_CHANNEL(channel)) << 8)
|
_AD5360_READ_CHANNEL(channel))
|
||||||
self.bus.set_xfer(self.chip_select, 0, 24)
|
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.read_async()
|
||||||
self.bus.set_xfer(self.chip_select, 24, 0)
|
self.bus.set_xfer(self.chip_select, 24, 0)
|
||||||
return self.bus.input_async() & 0xffff
|
return self.bus.input_async() & 0xffff
|
||||||
|
@ -91,5 +96,5 @@ class AD5360:
|
||||||
@kernel
|
@kernel
|
||||||
def load(self):
|
def load(self):
|
||||||
self.ldac.off()
|
self.ldac.off()
|
||||||
delay(24*ns)
|
delay_mu(3*self.bus.ref_period_mu)
|
||||||
self.ldac.on()
|
self.ldac.on()
|
||||||
|
|
|
@ -38,17 +38,16 @@ class SPIMaster:
|
||||||
* If desired, :meth:`write` ``data`` queuing the next
|
* If desired, :meth:`write` ``data`` queuing the next
|
||||||
(possibly chained) transfer.
|
(possibly chained) transfer.
|
||||||
|
|
||||||
:param ref_period: clock period of the SPI core.
|
|
||||||
:param channel: RTIO channel number of the SPI bus to control.
|
: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.core = dmgr.get("core")
|
||||||
self.ref_period = ref_period
|
self.ref_period_mu = seconds_to_mu(self.core.coarse_ref_period,
|
||||||
self.ref_period_mu = int(seconds_to_mu(ref_period, self.core))
|
self.core)
|
||||||
self.channel = channel
|
self.channel = channel
|
||||||
self.write_period_mu = int(0)
|
self.write_period_mu = int(0, 64)
|
||||||
self.read_period_mu = int(0)
|
self.read_period_mu = int(0, 64)
|
||||||
self.xfer_period_mu = int(0)
|
self.xfer_period_mu = int(0, 64)
|
||||||
# A full transfer takes write_period_mu + xfer_period_mu.
|
# A full transfer takes write_period_mu + xfer_period_mu.
|
||||||
# Chained transfers can happen every xfer_period_mu.
|
# Chained transfers can happen every xfer_period_mu.
|
||||||
# The second transfer of a chain can be written 2*ref_period_mu
|
# The second transfer of a chain can be written 2*ref_period_mu
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
"arguments": {"channel": 19}
|
"arguments": {"channel": 19}
|
||||||
},
|
},
|
||||||
|
|
||||||
"ams101_ldac": {
|
"ttl_ams101_ldac": {
|
||||||
"type": "local",
|
"type": "local",
|
||||||
"module": "artiq.coredevice.ttl",
|
"module": "artiq.coredevice.ttl",
|
||||||
"class": "TTLOut",
|
"class": "TTLOut",
|
||||||
|
@ -94,7 +94,7 @@
|
||||||
"arguments": {"channel": 21}
|
"arguments": {"channel": 21}
|
||||||
},
|
},
|
||||||
|
|
||||||
"ams101_spi": {
|
"spi_ams101": {
|
||||||
"type": "local",
|
"type": "local",
|
||||||
"module": "artiq.coredevice.spi",
|
"module": "artiq.coredevice.spi",
|
||||||
"class": "SPIMaster",
|
"class": "SPIMaster",
|
||||||
|
@ -108,6 +108,13 @@
|
||||||
"arguments": {"channel": 23}
|
"arguments": {"channel": 23}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"dac0": {
|
||||||
|
"type": "local",
|
||||||
|
"module": "artiq.coredevice.ad5360",
|
||||||
|
"class": "AD5360",
|
||||||
|
"arguments": {"spi_device": "spi0", "ldac_device": "ttl0"}
|
||||||
|
},
|
||||||
|
|
||||||
"dds_bus": {
|
"dds_bus": {
|
||||||
"type": "local",
|
"type": "local",
|
||||||
"module": "artiq.coredevice.dds",
|
"module": "artiq.coredevice.dds",
|
||||||
|
|
Loading…
Reference in New Issue