forked from M-Labs/artiq
sampler: fix reference voltage of recent hardware
This commit is contained in:
parent
261dc6b933
commit
c591e7e305
|
@ -12,6 +12,9 @@ Highlights:
|
||||||
* Implemented Phaser-MIQRO support. This requires the Phaser MIQRO gateware
|
* Implemented Phaser-MIQRO support. This requires the Phaser MIQRO gateware
|
||||||
variant.
|
variant.
|
||||||
* MSYS2 packaging for Windows.
|
* MSYS2 packaging for Windows.
|
||||||
|
* Sampler: adjusted ADC MU to Volt conversion base for Sampler since v2.2.
|
||||||
|
For earlier version please explicitly define it as an argument in the device database file
|
||||||
|
(e.g. ``"hw_rev": "v2.1"``).
|
||||||
|
|
||||||
ARTIQ-7
|
ARTIQ-7
|
||||||
-------
|
-------
|
||||||
|
|
|
@ -376,6 +376,9 @@
|
||||||
"minItems": 2,
|
"minItems": 2,
|
||||||
"maxItems": 2
|
"maxItems": 2
|
||||||
},
|
},
|
||||||
|
"sampler_hw_rev": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"urukul0_ports": {
|
"urukul0_ports": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
|
|
|
@ -15,21 +15,23 @@ SPI_CS_PGIA = 1 # separate SPI bus, CS used as RCLK
|
||||||
|
|
||||||
|
|
||||||
@portable
|
@portable
|
||||||
def adc_mu_to_volt(data, gain=0):
|
def adc_mu_to_volt(data, gain=0, corrected_fs=True):
|
||||||
"""Convert ADC data in machine units to Volts.
|
"""Convert ADC data in machine units to Volts.
|
||||||
|
|
||||||
:param data: 16 bit signed ADC word
|
:param data: 16 bit signed ADC word
|
||||||
:param gain: PGIA gain setting (0: 1, ..., 3: 1000)
|
:param gain: PGIA gain setting (0: 1, ..., 3: 1000)
|
||||||
|
:param corrected_fs: use corrected ADC FS reference.
|
||||||
|
Should be True for Samplers' revisions after v2.1. False for v2.1 and earlier.
|
||||||
:return: Voltage in Volts
|
:return: Voltage in Volts
|
||||||
"""
|
"""
|
||||||
if gain == 0:
|
if gain == 0:
|
||||||
volt_per_lsb = 20./(1 << 16)
|
volt_per_lsb = 20.48 / (1 << 16) if corrected_fs else 20. / (1 << 16)
|
||||||
elif gain == 1:
|
elif gain == 1:
|
||||||
volt_per_lsb = 2./(1 << 16)
|
volt_per_lsb = 2.048 / (1 << 16) if corrected_fs else 2. / (1 << 16)
|
||||||
elif gain == 2:
|
elif gain == 2:
|
||||||
volt_per_lsb = .2/(1 << 16)
|
volt_per_lsb = .2048 / (1 << 16) if corrected_fs else .2 / (1 << 16)
|
||||||
elif gain == 3:
|
elif gain == 3:
|
||||||
volt_per_lsb = .02/(1 << 16)
|
volt_per_lsb = 0.02048 / (1 << 16) if corrected_fs else .02 / (1 << 16)
|
||||||
else:
|
else:
|
||||||
raise ValueError("invalid gain")
|
raise ValueError("invalid gain")
|
||||||
return data * volt_per_lsb
|
return data * volt_per_lsb
|
||||||
|
@ -48,12 +50,13 @@ class Sampler:
|
||||||
:param gains: Initial value for PGIA gains shift register
|
:param gains: Initial value for PGIA gains shift register
|
||||||
(default: 0x0000). Knowledge of this state is not transferred
|
(default: 0x0000). Knowledge of this state is not transferred
|
||||||
between experiments.
|
between experiments.
|
||||||
|
:param hw_rev: Sampler's hardware revision string (default 'v2.2')
|
||||||
:param core_device: Core device name
|
:param core_device: Core device name
|
||||||
"""
|
"""
|
||||||
kernel_invariants = {"bus_adc", "bus_pgia", "core", "cnv", "div"}
|
kernel_invariants = {"bus_adc", "bus_pgia", "core", "cnv", "div", "corrected_fs"}
|
||||||
|
|
||||||
def __init__(self, dmgr, spi_adc_device, spi_pgia_device, cnv_device,
|
def __init__(self, dmgr, spi_adc_device, spi_pgia_device, cnv_device,
|
||||||
div=8, gains=0x0000, core_device="core"):
|
div=8, gains=0x0000, hw_rev="v2.2", core_device="core"):
|
||||||
self.bus_adc = dmgr.get(spi_adc_device)
|
self.bus_adc = dmgr.get(spi_adc_device)
|
||||||
self.bus_adc.update_xfer_duration_mu(div, 32)
|
self.bus_adc.update_xfer_duration_mu(div, 32)
|
||||||
self.bus_pgia = dmgr.get(spi_pgia_device)
|
self.bus_pgia = dmgr.get(spi_pgia_device)
|
||||||
|
@ -62,6 +65,11 @@ class Sampler:
|
||||||
self.cnv = dmgr.get(cnv_device)
|
self.cnv = dmgr.get(cnv_device)
|
||||||
self.div = div
|
self.div = div
|
||||||
self.gains = gains
|
self.gains = gains
|
||||||
|
self.corrected_fs = self.use_corrected_fs(hw_rev)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def use_corrected_fs(hw_rev):
|
||||||
|
return hw_rev != "v2.1"
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
def init(self):
|
def init(self):
|
||||||
|
@ -144,4 +152,4 @@ class Sampler:
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
channel = i + 8 - len(data)
|
channel = i + 8 - len(data)
|
||||||
gain = (self.gains >> (channel*2)) & 0b11
|
gain = (self.gains >> (channel*2)) & 0b11
|
||||||
data[i] = adc_mu_to_volt(adc_data[i], gain)
|
data[i] = adc_mu_to_volt(adc_data[i], gain, self.revision)
|
||||||
|
|
|
@ -23,12 +23,12 @@ def y_mu_to_full_scale(y):
|
||||||
|
|
||||||
|
|
||||||
@portable
|
@portable
|
||||||
def adc_mu_to_volts(x, gain):
|
def adc_mu_to_volts(x, gain, corrected_fs=True):
|
||||||
"""Convert servo ADC data from machine units to Volt."""
|
"""Convert servo ADC data from machine units to Volt."""
|
||||||
val = (x >> 1) & 0xffff
|
val = (x >> 1) & 0xffff
|
||||||
mask = 1 << 15
|
mask = 1 << 15
|
||||||
val = -(val & mask) + (val & ~mask)
|
val = -(val & mask) + (val & ~mask)
|
||||||
return sampler.adc_mu_to_volt(val, gain)
|
return sampler.adc_mu_to_volt(val, gain, corrected_fs)
|
||||||
|
|
||||||
|
|
||||||
class SUServo:
|
class SUServo:
|
||||||
|
@ -62,14 +62,15 @@ class SUServo:
|
||||||
:param gains: Initial value for PGIA gains shift register
|
:param gains: Initial value for PGIA gains shift register
|
||||||
(default: 0x0000). Knowledge of this state is not transferred
|
(default: 0x0000). Knowledge of this state is not transferred
|
||||||
between experiments.
|
between experiments.
|
||||||
|
:param sampler_hw_rev: Sampler's revision string
|
||||||
:param core_device: Core device name
|
:param core_device: Core device name
|
||||||
"""
|
"""
|
||||||
kernel_invariants = {"channel", "core", "pgia", "cplds", "ddses",
|
kernel_invariants = {"channel", "core", "pgia", "cplds", "ddses",
|
||||||
"ref_period_mu"}
|
"ref_period_mu", "corrected_fs"}
|
||||||
|
|
||||||
def __init__(self, dmgr, channel, pgia_device,
|
def __init__(self, dmgr, channel, pgia_device,
|
||||||
cpld_devices, dds_devices,
|
cpld_devices, dds_devices,
|
||||||
gains=0x0000, core_device="core"):
|
gains=0x0000, sampler_hw_rev="v2.2", core_device="core"):
|
||||||
|
|
||||||
self.core = dmgr.get(core_device)
|
self.core = dmgr.get(core_device)
|
||||||
self.pgia = dmgr.get(pgia_device)
|
self.pgia = dmgr.get(pgia_device)
|
||||||
|
@ -81,6 +82,7 @@ class SUServo:
|
||||||
self.gains = gains
|
self.gains = gains
|
||||||
self.ref_period_mu = self.core.seconds_to_mu(
|
self.ref_period_mu = self.core.seconds_to_mu(
|
||||||
self.core.coarse_ref_period)
|
self.core.coarse_ref_period)
|
||||||
|
self.corrected_fs = sampler.Sampler.use_corrected_fs(sampler_hw_rev)
|
||||||
assert self.ref_period_mu == self.core.ref_multiplier
|
assert self.ref_period_mu == self.core.ref_multiplier
|
||||||
|
|
||||||
@kernel
|
@kernel
|
||||||
|
@ -234,7 +236,7 @@ class SUServo:
|
||||||
"""
|
"""
|
||||||
val = self.get_adc_mu(channel)
|
val = self.get_adc_mu(channel)
|
||||||
gain = (self.gains >> (channel*2)) & 0b11
|
gain = (self.gains >> (channel*2)) & 0b11
|
||||||
return adc_mu_to_volts(val, gain)
|
return adc_mu_to_volts(val, gain, self.corrected_fs)
|
||||||
|
|
||||||
|
|
||||||
class Channel:
|
class Channel:
|
||||||
|
|
|
@ -410,10 +410,12 @@ class PeripheralManager:
|
||||||
"arguments": {{
|
"arguments": {{
|
||||||
"spi_adc_device": "spi_{name}_adc",
|
"spi_adc_device": "spi_{name}_adc",
|
||||||
"spi_pgia_device": "spi_{name}_pgia",
|
"spi_pgia_device": "spi_{name}_pgia",
|
||||||
"cnv_device": "ttl_{name}_cnv"
|
"cnv_device": "ttl_{name}_cnv",
|
||||||
|
"hw_rev": "{hw_rev}"
|
||||||
}}
|
}}
|
||||||
}}""",
|
}}""",
|
||||||
name=self.get_name("sampler"),
|
name=self.get_name("sampler"),
|
||||||
|
hw_rev=peripheral.get("hw_rev", "v2.2"),
|
||||||
adc_channel=rtio_offset,
|
adc_channel=rtio_offset,
|
||||||
pgia_channel=rtio_offset + 1,
|
pgia_channel=rtio_offset + 1,
|
||||||
cnv_channel=rtio_offset + 2)
|
cnv_channel=rtio_offset + 2)
|
||||||
|
@ -444,11 +446,13 @@ class PeripheralManager:
|
||||||
"channel": 0x{suservo_channel:06x},
|
"channel": 0x{suservo_channel:06x},
|
||||||
"pgia_device": "spi_{sampler_name}_pgia",
|
"pgia_device": "spi_{sampler_name}_pgia",
|
||||||
"cpld_devices": {cpld_names_list},
|
"cpld_devices": {cpld_names_list},
|
||||||
"dds_devices": {dds_names_list}
|
"dds_devices": {dds_names_list},
|
||||||
|
"sampler_hw_rev": "{sampler_hw_rev}"
|
||||||
}}
|
}}
|
||||||
}}""",
|
}}""",
|
||||||
suservo_name=suservo_name,
|
suservo_name=suservo_name,
|
||||||
sampler_name=sampler_name,
|
sampler_name=sampler_name,
|
||||||
|
sampler_hw_rev=peripheral.get("sampler_hw_rev", "v2.2"),
|
||||||
cpld_names_list=[urukul_name + "_cpld" for urukul_name in urukul_names],
|
cpld_names_list=[urukul_name + "_cpld" for urukul_name in urukul_names],
|
||||||
dds_names_list=[urukul_name + "_dds" for urukul_name in urukul_names],
|
dds_names_list=[urukul_name + "_dds" for urukul_name in urukul_names],
|
||||||
suservo_channel=rtio_offset+next(channel))
|
suservo_channel=rtio_offset+next(channel))
|
||||||
|
|
Loading…
Reference in New Issue