Commit 308db744 authored by Matthieu Cattin's avatar Matthieu Cattin

test28: Work on acquisition configuration.

parent 8c14b2b4
......@@ -70,10 +70,11 @@ NB_CHANNELS = 4
SSR_SET_SLEEP = 0.05
DAC_SET_SLEEP = 0.01 # in [s]
SAMPLE_WIDTH = 2 # bytes
MEMORY_SIZE = 2^28/(NB_CHANNELS * SAMPLE_WIDTH) # samples
MULTISHOT_MAX_SIZE = 2^11 # samples
MEMORY_SIZE = 2**28/(NB_CHANNELS * SAMPLE_WIDTH) # samples
MULTISHOT_MAX_SIZE = 2**11 # samples
ACQ_TIMEOUT = 10
SAMP_FREQ = 100E6 # Hz
RANGES = {'10V':10.0, '1V':1.0, '100mV':0.1}
# Acquisition
ACQ_MIN_PERIODS = 2
......@@ -89,10 +90,49 @@ SINE_MAX_AMPL = 5.0 # Vpeak
# Functions declaration
################################################################################
# Converts two's complement hex to signed
def hex2signed(value):
if(value & 0x8000):
return -((~value & 0xFFFF) + 1)
else:
return value
# Converts signed to two's complement hex
def signed2hex(value):
if value < 0:
return (((abs(value) ^ 0xffff) + 1) & 0xffff)
else:
return value
# Converts digital value to volts
def digital2volt(value, full_scale, nb_bit):
return float(value) * float(full_scale)/2**nb_bit
# Converts volts to digital value with half full range offset
def volt2digital(value, full_scale, nb_bit):
digital = (value + full_scale/2) * 2**nb_bit/full_scale
if(digital > 2**nb_bit - 1):
digital = 2**nb_bit - 1
if(digital < 0):
digital = 0
#print('volt2digital: %2.9f > %2.9f')%(value,digital)
return int(digital)
# Converts volts to digital value
def volt2digital_without_offset(value, full_scale, nb_bit):
if(value > (2**nb_bit)/2 - 1):
value = (2**nb_bit)/2 - 1
if(value < -((2**nb_bit)/2)):
value = -((2**nb_bit)/2)
digital = (value) * 2**nb_bit/full_scale
#print('volt2digital: %2.9f > %2.9f')%(value,digital)
return int(digital)
# Clear DDR memory (fill with zeros)
def clear_ddr(carrier, verbose=False):
# dma item size = 4096 bytes
# max linked items = 128
# 2^25/(4096*128) = 64
# 2**25/(4096*128) = 64
item_size = 4096
max_items = 128
pattern = 0x0
......@@ -104,6 +144,7 @@ def clear_ddr(carrier, verbose=False):
if verbose:
print("DMA #%d"%i)
# Set AWG (sine wave)
def set_awg(awg, freq, ampl, offset, verbose=False):
# Set sine params
sine = SineWaveform()
......@@ -117,7 +158,8 @@ def set_awg(awg, freq, ampl, offset, verbose=False):
awg.play(sine)
awg.output = True
def get_best_input_range(in_ampl, term):
# Get best adc input range for a given amplitude
def get_best_input_range(in_ampl, term, verbose=False):
# If the 50 ohms termination is enabled, input amplitude is reduced by a factor 2
if term == 'ON':
in_ampl = in_ampl/2.0
......@@ -126,22 +168,51 @@ def get_best_input_range(in_ampl, term):
in_range = '1V'
if in_ampl > 0.5:
in_range = '10V'
if verbose:
print("Selected input range: %s"%in_range)
return in_range
# Set acquisition params
def set_acq(fmc, nb_shots, pre_trig_samples, post_trig_samples, decim_factor, verbose=False):
fmc.set_pre_trig_samples(pre_trig_samples)
fmc.set_post_trig_samples(post_trig_samples)
fmc.set_shots(nb_shots)
fmc.set_decimation(decim_factor)
if verbose:
print("Acquisition params -> number of shots: %d, pre-trigger samples: %d, post-trigger samples: %d, decimation factor: %d"%(nb_shots, pre_trig_samples, post_trig_samples, decim_factor))
def set_acq():
# Set acquisition
fmc.set_pre_trig_samples(PRE_TRIG_SAMPLES)
fmc.set_post_trig_samples(POST_TRIG_SAMPLES)
fmc.set_shots(NB_SHOTS)
set_trig_config(hw_sel, hw_pol, hw_en, sw_en, channel, int_thres, delay)
set_decimation(factor)
set_input_term(channel, state)
set_dc_offset(channel, value)
set_input_range(channel, in_range)
# Set analog input range and termination (same on all channels)
def set_adc_input(fmc, term, in_range, verbose=False):
for channel in range(1,NB_CHANNELS+1):
fmc.set_input_term(channel, term)
fmc.set_input_range(channel, in_range)
time.sleep(SSR_SET_SLEEP)
if verbose:
print("ADC input params -> Termination: %s, input range: %s"%(term, in_range))
# Set channel offset with the DAC (same on all channels)
def set_adc_offset(fmc, offset_volt, verbose=False):
dac_fs = 10.0
dac_nbits = 16
dac_d = volt2digital(offset_volt, dac_fs, dac_nbits)
if verbose:
print('Offset DAC value: 0x%X (%fV)')%(dac_d, offset_volt)
for channel in range(1,NB_CHANNELS+1):
fmc.set_dc_offset(channel,dac_d)
time.sleep(DAC_SET_SLEEP)
# Set hardware trigger
def set_adc_trig(fmc, hw_sel, hw_pol, channel, thres_volt, delay, in_range, verbose=False):
fs = RANGES[in_range]
nbits = 16
thres = volt2digital(thres_volt, fs, nbits)
hw_en = 1
sw_en = 0
fmc.set_trig_config(hw_sel, hw_pol, hw_en, sw_en, channel, thres, delay)
HW_SEL = ['internal', 'external']
HW_POL = ['rising','falling']
if verbose:
print("Trigger params -> Hardware %s on %s edge, on channel %d with a thresold of 0x%X (%fV)"%(HW_SEL[hw_sel], HW_POL[hw_pol], channel, thres, thres_volt))
......@@ -261,40 +332,64 @@ def main (default_directory='.'):
awg = Agilent33250A(device=awg_tty[0], bauds=AWG_BAUD)
box = CCalibr_box(box_tty[0])
print("Clearing DDR memory...")
# Clear DDR
t1 = time.time()
#clear_ddr(carrier, False)
t2 = time.time()
print "elapsed time: %.2f seconds\n" % (t2-t1)
print("Building input sine wave...")
# Building input sine wave
sine_freq = SINE_MIN_FREQ + ((SINE_MAX_FREQ-SINE_MIN_FREQ)*rdm.random())
sine_ampl = SINE_MIN_AMPL + ((SINE_MAX_AMPL-SINE_MIN_AMPL)*rdm.random())
sine_off = (SINE_MAX_AMPL-sine_ampl)*rdm.random()
print("Input sine wave => Frequency: %3.3fMHz, Amplitude: %2.3fVp, Offset: %2.3fV"%(sine_freq/1E6, sine_ampl, sine_off))
sine_offset = (SINE_MAX_AMPL-sine_ampl)*rdm.random()
print("Input sine wave => Frequency: %3.3fMHz, Amplitude: %2.3fVp, Offset: %2.3fV"%(sine_freq/1E6, sine_ampl, sine_offset))
print("Setting AWG...")
set_awg(awg, sine_freq, sine_ampl, sine_off)
# Configure AWG with sine wave
set_awg(awg, sine_freq, sine_ampl, sine_offset)
print("Choosing input termination...")
# Choose input termination randomly
adc_term = rdm.choice(['ON', 'OFF'])
print("Input termination: %s"%adc_term)
print("Finding best adc input range...")
adc_range = get_best_input_range(sine_ampl, adc_term)
print("Selected input range: %s"%adc_range)
# Find best input range given the sine wave amplitude
adc_range = get_best_input_range(sine_ampl, adc_term, True)
# min_periods = 2
# samp_freq = 100E6
# sine_freq = x
# => min_samples = 2*samp_freq/sine_freq
acq_min_samples = ACQ_MIN_PERIODS*SAMP_FREQ/sine_freq
print("Minimum number of samples: %d"%acq_min_samples)
# Configure ADC analogue input
set_adc_input(fmc, adc_term, adc_range, True)
adc_offset = -sine_offset
set_adc_offset(fmc, adc_offset, True)
#acq_samples = acq_min_samples +
# Configure trigger
trig_hw_sel = 1 # external
trig_hw_pol = 0 # rising
trig_channel = 1
trig_thres = 0
trig_delay = 0
set_adc_trig(fmc, trig_hw_sel, trig_hw_pol, trig_channel, trig_thres, trig_delay, adc_range, True)
# acq_max_nb_shots =
# Find the minimum number of samples to have ACQ_MIN_PERIODS of the sine wave
acq_min_samples = ACQ_MIN_PERIODS*SAMP_FREQ/sine_freq
print("Minimum number of samples: %d"%acq_min_samples)
# Choose the number of samples randomly
multishot = False
if multishot:
acq_samples = rdm.randrange(acq_min_samples, MULTISHOT_MAX_SIZE+1)
acq_nb_shots = rdm.randrange(1, (MEMORY_SIZE/acq_samples)+1)
else:
acq_samples = rdm.randrange(acq_min_samples, MEMORY_SIZE+1)
acq_nb_shots = 1
# Choose the trigger position randomly
acq_pre_trig_samples = rdm.randrange(0, acq_samples+1)
acq_post_trig_samples = acq_samples - acq_pre_trig_samples
# Configure acquisition
acq_decim_factor = 1
set_acq(fmc, acq_nb_shots, acq_pre_trig_samples, acq_post_trig_samples, acq_ decim_factor, True)
# Get data from DDR
#data = carrier.get_data(0, 50000*8)
#plot_all(data, max(data))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment