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
|
||||
variant.
|
||||
* 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
|
||||
-------
|
||||
|
@ -376,6 +376,9 @@
|
||||
"minItems": 2,
|
||||
"maxItems": 2
|
||||
},
|
||||
"sampler_hw_rev": {
|
||||
"type": "string"
|
||||
},
|
||||
"urukul0_ports": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
@ -15,24 +15,26 @@ SPI_CS_PGIA = 1 # separate SPI bus, CS used as RCLK
|
||||
|
||||
|
||||
@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.
|
||||
|
||||
:param data: 16 bit signed ADC word
|
||||
: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
|
||||
"""
|
||||
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:
|
||||
volt_per_lsb = 2./(1 << 16)
|
||||
volt_per_lsb = 2.048 / (1 << 16) if corrected_fs else 2. / (1 << 16)
|
||||
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:
|
||||
volt_per_lsb = .02/(1 << 16)
|
||||
volt_per_lsb = 0.02048 / (1 << 16) if corrected_fs else .02 / (1 << 16)
|
||||
else:
|
||||
raise ValueError("invalid gain")
|
||||
return data*volt_per_lsb
|
||||
return data * volt_per_lsb
|
||||
|
||||
|
||||
class Sampler:
|
||||
@ -48,12 +50,13 @@ class Sampler:
|
||||
:param gains: Initial value for PGIA gains shift register
|
||||
(default: 0x0000). Knowledge of this state is not transferred
|
||||
between experiments.
|
||||
:param hw_rev: Sampler's hardware revision string (default 'v2.2')
|
||||
: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,
|
||||
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.update_xfer_duration_mu(div, 32)
|
||||
self.bus_pgia = dmgr.get(spi_pgia_device)
|
||||
@ -62,6 +65,11 @@ class Sampler:
|
||||
self.cnv = dmgr.get(cnv_device)
|
||||
self.div = div
|
||||
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
|
||||
def init(self):
|
||||
@ -144,4 +152,4 @@ class Sampler:
|
||||
for i in range(n):
|
||||
channel = i + 8 - len(data)
|
||||
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
|
||||
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."""
|
||||
val = (x >> 1) & 0xffff
|
||||
mask = 1 << 15
|
||||
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:
|
||||
@ -62,14 +62,15 @@ class SUServo:
|
||||
:param gains: Initial value for PGIA gains shift register
|
||||
(default: 0x0000). Knowledge of this state is not transferred
|
||||
between experiments.
|
||||
:param sampler_hw_rev: Sampler's revision string
|
||||
:param core_device: Core device name
|
||||
"""
|
||||
kernel_invariants = {"channel", "core", "pgia", "cplds", "ddses",
|
||||
"ref_period_mu"}
|
||||
"ref_period_mu", "corrected_fs"}
|
||||
|
||||
def __init__(self, dmgr, channel, pgia_device,
|
||||
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.pgia = dmgr.get(pgia_device)
|
||||
@ -81,6 +82,7 @@ class SUServo:
|
||||
self.gains = gains
|
||||
self.ref_period_mu = self.core.seconds_to_mu(
|
||||
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
|
||||
|
||||
@kernel
|
||||
@ -234,7 +236,7 @@ class SUServo:
|
||||
"""
|
||||
val = self.get_adc_mu(channel)
|
||||
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:
|
||||
|
@ -410,10 +410,12 @@ class PeripheralManager:
|
||||
"arguments": {{
|
||||
"spi_adc_device": "spi_{name}_adc",
|
||||
"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"),
|
||||
hw_rev=peripheral.get("hw_rev", "v2.2"),
|
||||
adc_channel=rtio_offset,
|
||||
pgia_channel=rtio_offset + 1,
|
||||
cnv_channel=rtio_offset + 2)
|
||||
@ -444,11 +446,13 @@ class PeripheralManager:
|
||||
"channel": 0x{suservo_channel:06x},
|
||||
"pgia_device": "spi_{sampler_name}_pgia",
|
||||
"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,
|
||||
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],
|
||||
dds_names_list=[urukul_name + "_dds" for urukul_name in urukul_names],
|
||||
suservo_channel=rtio_offset+next(channel))
|
||||
|
Loading…
Reference in New Issue
Block a user