Commit a494c578 authored by Matthieu Cattin's avatar Matthieu Cattin

Create functions to simplify code.

parent 074d95e6
......@@ -31,61 +31,64 @@ test19: Calibration
Note: Requires test00.py to run first to load the firmware!
"""
GN4124_CSR = 0x0
# Calibration box vendor and product IDs
BOX_USB_VENDOR_ID = 0x10c4 # Cygnal Integrated Products, Inc.
BOX_USB_PRODUCT_ID = 0xea60 # CP210x Composite Device
# Agilent AWG serial access vendor and product IDs
AWG_USB_VENDOR_ID = 0x0403 # Future Technology Devices International, Ltd
AWG_USB_PRODUCT_ID = 0x6001 # FT232 USB-Serial (UART) IC
RS232_BAUD = 57600
AWG_BAUD = 57600
NB_CHANNELS = 4
AWG_SET_SLEEP = 1
SSR_SET_SLEEP = 0.05
BOX_SET_SLEEP = 1
DAC_SET_SLEEP = 0.1
AWG_SET_SLEEP = 0.1
SSR_SET_SLEEP = 0.005
BOX_SET_SLEEP = 0.01
DAC_SET_SLEEP = 0.01
ACQ_TIMEOUT = 10
MAX_FIRMWARE_RELOAD = 10
PRE_TRIG_SAMPLES = 1000
PRE_TRIG_SAMPLES = 100
POST_TRIG_SAMPLES = 100000
NB_SHOTS = 1
ACQ_LENGTH = 50000 # in samples
DMA_LENGTH = 4096 # in bytes
ADC_NBITS = 16 # ADC chip is 14 bits, but shifted to 16 bits in the firmware
DAC_NBITS = 16
DAC_FS = 10 # DAC full scale range is 10V
# Full scale volatge values for input ranges
ADC_FS = {'10V':10.0, '1V':1.0, '100mV':0.1}
RANGES = ['10V', '1V', '100mV']
# Number of repeatition of the measurement, then the results are averaged
REPEAT = 2
ADC_LSB = {'10V':10.0/2**14, '1V':1.0/2**14, '100mV':0.1/2**14}
def load_firmware(default_directory):
print('Load firmware to FPGA')
path_fpga_loader = '../../../gnurabbit/user/fpga_loader';
path_firmware = '../firmwares/spec_fmcadc100m14b4cha_test.bin';
firmware_loader = os.path.join(default_directory, path_fpga_loader)
bitstream = os.path.join(default_directory, path_firmware)
print firmware_loader + ' ' + bitstream + '\n'
os.system( firmware_loader + ' ' + bitstream )
time.sleep(2);
def disconnect_channels(fmc):
for i in range(1,NB_CHANNELS+1):
fmc.set_ssr(i, 0x00)
time.sleep(SSR_SET_SLEEP)
def fmc_adc_init(spec, fmc):
print('Initialise FMC board\n')
fmc.__init__(spec)
# Reset offset DACs
fmc.dc_offset_reset()
# Make sure all switches are OFF
......@@ -101,52 +104,6 @@ def fmc_adc_init(spec, fmc):
# Print configuration
#fmc.print_adc_core_config()
def acquisition_all(fmc, spec_fmc):
# Make sure no acquisition is running
fmc.stop_acq()
#print('Acquisition FSM state : %s') % fmc.get_acq_fsm_state()
# Start acquisition
fmc.start_acq()
time.sleep(0.01)
# Trigger
fmc.sw_trig()
# Wait end of acquisition
timeout = 0
while('IDLE' != fmc.get_acq_fsm_state()):
#print fmc.get_acq_fsm_state()
time.sleep(.1)
timeout += 1
if(ACQ_TIMEOUT < timeout):
print('Acquisition timeout. Check that the AWG is switched ON and properly connected.')
return 1
# Retrieve data trough DMA
trig_pos = fmc.get_trig_pos()
#print('Trigger position; 0x%X')%(trig_pos)
channels_data = spec_fmc.get_data((trig_pos<<3), ACQ_LENGTH*8)
#channels_data = spec_fmc.get_data(0x0, ACQ_LENGTH*8)
return channels_data
def plot_all(data, mean, ylimit):
sample = arange(len(data)/4)
clf()
plot(sample, data[0::4], 'b', label='Channel 1')
plot(sample, data[1::4], 'g', label='Channel 2')
plot(sample, data[2::4], 'c', label='Channel 3')
plot(sample, data[3::4], 'm', label='Channel 4')
plot(sample, [mean[0]]*len(sample), 'r')
plot(sample, [mean[1]]*len(sample), 'r')
plot(sample, [mean[2]]*len(sample), 'r')
plot(sample, [mean[3]]*len(sample), 'r')
ylim(-ylimit-(ylimit/10.0), ylimit+(ylimit/10.0))
grid(which='both')
legend()
draw()
show()
return 0
# Converts two's complement hex to signed
def hex2signed(value):
if(value & 0x8000):
......@@ -161,12 +118,10 @@ def signed2hex(value):
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
......@@ -177,7 +132,6 @@ def volt2digital(value, full_scale, nb_bit):
#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):
......@@ -188,8 +142,56 @@ def volt2digital_without_offset(value, full_scale, nb_bit):
#print('volt2digital: %2.9f > %2.9f')%(value,digital)
return int(digital)
def acq_channel(spec_fmc, fmc, ch, adc_fs, adc_nbits=16, pause=0.01):
# Make sure no acquisition is running
fmc.stop_acq()
# Start acquisition
fmc.start_acq()
#time.sleep(pause)
# Trigger
fmc.sw_trig()
# Wait end of acquisition
timeout = 0
time.sleep(0.001)
while('IDLE' != fmc.get_acq_fsm_state()):
time.sleep(0.01)
timeout += 1
if(ACQ_TIMEOUT < timeout):
print "Acquisition timeout. Missing trigger?."
print "Acq FSM state: %s"%fmc.get_acq_fsm_state()
return 1
# Retrieve data trough DMA
trig_pos = fmc.get_trig_pos()
# Enable "DMA done" iinterrupt
spec_fmc.set_irq_en_mask(0x1)
# Read ACQ_LENGTH samples after the trigger for all channels
channels_data = spec_fmc.get_data((trig_pos<<3), ACQ_LENGTH*8)
# Disable "DMA done" iinterrupt
spec_fmc.set_irq_en_mask(0x0)
channels_data = [hex2signed(item) for item in channels_data]
channels_data = [digital2volt(item,adc_fs,adc_nbits) for item in channels_data]
channel_data = channels_data[ch-1::4]
return mean(channel_data)
def plot_all(data, mean, ylimit):
sample = arange(len(data)/4)
clf()
plot(sample, data[0::4], 'b', label='Channel 1')
plot(sample, data[1::4], 'g', label='Channel 2')
plot(sample, data[2::4], 'c', label='Channel 3')
plot(sample, data[3::4], 'm', label='Channel 4')
plot(sample, [mean[0]]*len(sample), 'r')
plot(sample, [mean[1]]*len(sample), 'r')
plot(sample, [mean[2]]*len(sample), 'r')
plot(sample, [mean[3]]*len(sample), 'r')
ylim(-ylimit-(ylimit/10.0), ylimit+(ylimit/10.0))
grid(which='both')
legend()
draw()
show()
return 0
def set_offset_dac(fmc, dac_fs, dac_nbits, channel, offset_volt, dac_corr_flag=False):
def set_offset_dac(fmc, channel, offset_volt, dac_fs=10.0, dac_nbits=16, dac_corr_flag=False):
dac_v = offset_volt
dac_d = volt2digital(dac_v,dac_fs,dac_nbits)
#print('DAC value: 0x%X (%fV)')%(dac_d, dac_v)
......@@ -199,43 +201,40 @@ def set_offset_dac(fmc, dac_fs, dac_nbits, channel, offset_volt, dac_corr_flag=F
fmc.set_dc_offset(channel,dac_d)
time.sleep(DAC_SET_SLEEP)
def get_mean_value(adc_fs, adc_nbits, acq):
mean_d = []
for channel in range(1,NB_CHANNELS+1):
mean_d.append(mean(acq[channel-1::4]))
mean_v = [digital2volt(item,adc_fs,adc_nbits) for item in mean_d]
return mean_v
def set_box_dac_range(box, fmc, box_out, dac_value, in_range, dac_corr_flag=False):
# Set calibration box output
box.select_output(box_out)
def make_meas(spec_fmc, fmc, box, dac_value, in_value, in_range, adc_fs, repeat):
ch_meas = []
ch_diff = []
for ch in range(1,NB_CHANNELS+1):
# Set offset DAC
set_offset_dac(fmc, ch, dac_value)
# Configure calibration box
if in_value == 0.0:
# Configure analogue input, ground input
fmc.set_input_range(ch, ('CAL_'+in_range))
time.sleep(SSR_SET_SLEEP)
# Connect AWG to current channel
box.select_output_ch(ch)
time.sleep(BOX_SET_SLEEP)
# Set offset DACs
for channel in range(1,NB_CHANNELS+1):
set_offset_dac(fmc, DAC_FS, DAC_NBITS, channel, dac_value, dac_corr_flag)
# Set channels input range
for channel in range(1,NB_CHANNELS+1):
fmc.set_input_range(channel, in_range)
else:
# Configure analogue input range
fmc.set_input_range(ch, in_range)
time.sleep(SSR_SET_SLEEP)
def channels_mean(spec_fmc, fmc, ADC_FS, print_flag, plot_flag=False):
# Measures value on each channel
acq_d = acquisition_all(fmc, spec_fmc)
acq_d = [hex2signed(item) for item in acq_d]
acq_v = [digital2volt(item,ADC_FS,ADC_NBITS) for item in acq_d]
mean_v = get_mean_value(ADC_FS, ADC_NBITS, acq_d)
if(True == print_flag):
print('\n')
for channel in range(1,NB_CHANNELS+1):
print('Channel %d: mean voltage = %2.9fV')%(channel, mean_v[channel-1])
if(True == plot_flag):
plot_all(acq_v, mean_v, ADC_FS/2.0)
return mean_v
# Connect Vref for selected input range to current channel
# Note that channel in parameter is the one connected to AWG
if ch == 1:
awg_ch = 4
else:
awg_ch = ch-1
box.select_output_ch(awg_ch, in_range)
time.sleep(BOX_SET_SLEEP)
# Perform an acquisition
meas = []
for i in range(repeat):
meas.append(acq_channel(spec_fmc, fmc, ch, adc_fs))
# Calculate mean and delta of acquisitions
ch_meas.append(mean(meas))
ch_diff.append(max(meas)-min(meas))
return ch_meas, ch_diff
# Calculates ADC + input stage gain
......@@ -254,18 +253,6 @@ def calc_gd(Vm1, Vm2, Vm3, Vref1, Vref2):
def calc_od(Vm1, Vm2, Vm3, Vm4, Vref1):
return ((Vref1*(Vm1-Vm2-Vm3+Vm4))/(Vm1-Vm2))
def dump_file_to_eeprom(fmc, filename):
eeprom_content = []
eeprom_addr = []
print filename
f = open(filename,"r+")
for line in f:
addr,data=line.split()
eeprom_content.append(int(data,2))
eeprom_addr.append(int(addr,2))
fmc.sys_i2c_eeprom_write(eeprom_addr[0],eeprom_content)
return 0
def main (default_directory = '.'):
......@@ -281,14 +268,10 @@ def main (default_directory = '.'):
box_tty = usb_tty.find_usb_tty(BOX_USB_VENDOR_ID, BOX_USB_PRODUCT_ID)
#print "AWG:%s"%awg_tty[0]
#print "BOX:%s"%box_tty[0]
gen = Agilent33250A(device=awg_tty[0], bauds=RS232_BAUD)
gen = Agilent33250A(device=awg_tty[0], bauds=AWG_BAUD)
sine = SineWaveform()
box = calibr_box.CCalibr_box(box_tty[0])
box_eeprom = cp210x_eeprom.CCP210x_Eeprom("%X"%BOX_USB_VENDOR_ID, "%X"%BOX_USB_PRODUCT_ID)
box_calibr_data = box_eeprom.get_calibr_data()
# Enable "DMA finished" IRQ
spec_fmc.set_irq_en_mask(0x1)
# Initialise fmc adc
fmc_adc_init(spec, fmc)
......@@ -296,8 +279,9 @@ def main (default_directory = '.'):
# Connect to AWG
gen.connect()
# Switch AWG output OFF
# Switch AWG output and sync OFF
gen.output = False
gen.sync = False
# Measure FMC and carrier temperature
print('SPEC temperature: %3.3f°C') % spec_fmc.get_temp()
......@@ -309,400 +293,160 @@ def main (default_directory = '.'):
fmc.set_input_term(channel, 'OFF')
fmc.dc_offset_reset()
# Get calibration data from calibration box
box_calibr_data = box_eeprom.get_calibr_data()
print "\nCalibration box data:"
print box_calibr_data
# Offset DAC reference voltage
offset_dac_data = {'10V':4.096, '1V':0.4096, '100mV':0.04096}
print "\nOffset DAC reference volatges:"
print offset_dac_data
# Dict to store ADC calibration data
adc_corr_data = {'10V':{'offset':[],'gain':[]},
'1V':{'offset':[],'gain':[]},
'100mV':{'offset':[],'gain':[]}}
# Number of repeatition of the measurement, then the results are averaged
REPEAT = 5
# Dict to store DAC calibration data
dac_corr_data = {'10V':{'offset':[],'gain':[]},
'1V':{'offset':[],'gain':[]},
'100mV':{'offset':[],'gain':[]}}
############################################################################
# 10V range calibration
# Calibration
############################################################################
print('\n10V range calibration\n----------------------------------')
# ADC full scale is 100mV
ADC_FS = 10.0
# Reference voltage for calibration
Vref1 = float(box_calibr_data['10V']) # from box cailbration data in CP2103 EEPROM
Vref2 = 4.096 # reference voltage to set offset DAC
#---------------------------------------------------------------------------
# Measure 1
# Channel input = 0V, offset DAC = 0V
#---------------------------------------------------------------------------
print('\nMeasurement 1: channel input = 0V, offset DAC = 0V')
set_box_dac_range(box, fmc, 'AWG', 0.0, 'CAL_10V')
vm1 = []
for i in range(REPEAT):
vm1.append(channels_mean(spec_fmc, fmc, ADC_FS, False))
Vm1 = [mean([row[n] for row in vm1]) for n in range(NB_CHANNELS)]
for channel in range(1,NB_CHANNELS+1):
print('Channel %d: Vm1=%02.9fV')%(channel, Vm1[channel-1])
#---------------------------------------------------------------------------
# Measure 2
# Channel input = Vref = 4.096V, offset DAC = 0V
#---------------------------------------------------------------------------
print('\nMeasurement 2: channel input = Vref = %1.8fV, offset DAC = 0V')%(Vref1)
set_box_dac_range(box, fmc, '10V', 0.0, '10V')
vm2 = []
for i in range(REPEAT):
vm2.append(channels_mean(spec_fmc, fmc, ADC_FS, False))
Vm2 = [mean([row[n] for row in vm2]) for n in range(NB_CHANNELS)]
for channel in range(1,NB_CHANNELS+1):
print('Channel %d: Vm2=%02.9fV')%(channel, Vm2[channel-1])
#---------------------------------------------------------------------------
# Measure 3
# Channel input = 0V, offset DAC = Vref = 4.096V
#---------------------------------------------------------------------------
print('\nMeasurement 3: channel input = 0V, offset DAC = Vref = %1.8fV')%(Vref2)
set_box_dac_range(box, fmc, 'AWG', Vref2, 'CAL_10V')
error = 0
for IN_RANGE in RANGES:
vm3 = []
for i in range(REPEAT):
vm3.append(channels_mean(spec_fmc, fmc, ADC_FS, False))
Vm3 = [mean([row[n] for row in vm3]) for n in range(NB_CHANNELS)]
for channel in range(1,NB_CHANNELS+1):
print('Channel %d: Vm3=%02.9fV')%(channel, Vm3[channel-1])
print "\n%s range calibration\n----------------------------------\n"%(IN_RANGE)
#---------------------------------------------------------------------------
# Measure 4
# Channel input = Vref = 4.096, offset DAC = Vref = 4.096
#---------------------------------------------------------------------------
print('SPEC temperature: %3.3f°C') % spec_fmc.get_temp()
print('FMC temperature : %3.3f°C') % fmc.get_temp()
print('\nMeasurement 4: channel input = Vref = %1.8fV, offset DAC = Vref = %1.8fV')%(Vref1, Vref2)
print "\nADC LSB:%1.9f"%(ADC_LSB[IN_RANGE])
set_box_dac_range(box, fmc, '10V', Vref2, '10V')
# Reference voltage for calibration
vref_in = float(box_calibr_data[IN_RANGE]) # from box cailbration data in CP2103 EEPROM
vref_dac = offset_dac_data[IN_RANGE] # reference voltage to set offset DAC
# Input and offset DAC volatges for the four measurements
v_in = [0.0, vref_in, 0.0, vref_in]
v_dac = [0.0, 0.0, vref_dac, vref_dac]
#-----------------------------------------------------------------------
# Make the measurements
#-----------------------------------------------------------------------
v_meas = []
d_meas = []
error = 0
for i in range(len(v_in)):
print "\nMeasurement %d: channel input = %2.8fV, offset DAC = %2.8fV"%((i+1), v_in[i], v_dac[i])
mean, diff = make_meas(spec_fmc, fmc, box, v_dac[i], v_in[i], IN_RANGE, ADC_FS[IN_RANGE], REPEAT)
v_meas.append(mean)
d_meas.append(diff)
for ch in range(1,NB_CHANNELS+1):
print "Channel %d: v_meas=%02.9fV delta=%1.9f"%(ch, v_meas[i][ch-1], d_meas[i][ch-1])
print " Check voltage stability"
meas = d_meas[i][ch-1]
expect = (2*ADC_LSB[IN_RANGE])
if meas > expect:
print " ERROR: measure:%1.9f expect:%1.9f"%(meas, expect)
error += 1
else:
print " OK"
vm4 = []
for i in range(REPEAT):
vm4.append(channels_mean(spec_fmc, fmc, ADC_FS, False))
Vm4 = [mean([row[n] for row in vm4]) for n in range(NB_CHANNELS)]
for channel in range(1,NB_CHANNELS+1):
print('Channel %d: Vm4=%02.9fV')%(channel, Vm4[channel-1])
#---------------------------------------------------------------------------
#-----------------------------------------------------------------------
# Calculate gain and offset parameters
# ga = ADC + input stage gain
# oa = ADC + input stage offset
# gd = DAC gain
# od = DAC offset
#---------------------------------------------------------------------------
print('\n10V range correction parameters\n----------------------------------')
#-----------------------------------------------------------------------
print "\n%s range correction parameters\n----------------------------------"%(IN_RANGE)
ga = []
for channel in range(1,NB_CHANNELS+1):
ga.append(calc_ga(Vm1[channel-1], Vm2[channel-1], Vref1))
print('Channel %d ADC gain coeff: %02.9f')%(channel, ga[channel-1])
for ch in range(1,NB_CHANNELS+1):
ga.append(calc_ga(v_meas[0][ch-1], v_meas[1][ch-1], vref_in))
print "Channel %d ADC gain coeff: %02.9f"%(ch, ga[ch-1])
oa = []
for channel in range(1,NB_CHANNELS+1):
oa.append(calc_oa(Vm2[channel-1], Vm3[channel-1], Vm4[channel-1]))
print('Channel %d ADC offset : %02.9f')%(channel, oa[channel-1])
for ch in range(1,NB_CHANNELS+1):
oa.append(calc_oa(v_meas[1][ch-1], v_meas[2][ch-1], v_meas[3][ch-1]))
print "Channel %d ADC offset : %02.9f"%(ch, oa[ch-1])
gd = []
for channel in range(1,NB_CHANNELS+1):
gd.append(calc_gd(Vm1[channel-1], Vm2[channel-1], Vm3[channel-1], Vref1, Vref2))
print('Channel %d DAC gain coeff: %02.9f')%(channel, gd[channel-1])
for ch in range(1,NB_CHANNELS+1):
gd.append(calc_gd(v_meas[0][ch-1], v_meas[1][ch-1], v_meas[2][ch-1], vref_in, vref_dac))
print "Channel %d DAC gain coeff: %02.9f"%(ch, gd[ch-1])
od = []
for channel in range(1,NB_CHANNELS+1):
od.append(calc_od(Vm1[channel-1], Vm2[channel-1], Vm3[channel-1], Vm4[channel-1], Vref1))
print('Channel %d DAC offset : %02.9f')%(channel, od[channel-1])
#---------------------------------------------------------------------------
# Calculate correction register values
#---------------------------------------------------------------------------
for ch in range(1,NB_CHANNELS+1):
od.append(calc_od(v_meas[0][ch-1], v_meas[1][ch-1], v_meas[2][ch-1], v_meas[3][ch-1], vref_in))
print "Channel %d DAC offset : %02.9f"%(ch, od[ch-1])
#-----------------------------------------------------------------------
# Calculate ADC correction register values
#-----------------------------------------------------------------------
# 0x8000 corresponds to 1.0
# Gain correction register is written with 1/gain * 1.0
adc_corr_data['10V']['gain'] = [int(round((1/item)*0x8000)) for item in ga]
adc_corr_data[IN_RANGE]['gain'] = [int(round((1/item)*0x8000)) for item in ga]
# oa is in volts and has to be converted to digital raw value,
# to be written in offset correction register
adc_corr_data['10V']['offset'] = [-(volt2digital_without_offset(item,ADC_FS,ADC_NBITS)) for item in oa]
############################################################################
# 1V range calibration
############################################################################
print('\n1V range calibration\n----------------------------------')
# ADC full scale is 100mV
ADC_FS = 1.0
# Reference voltage for calibration
Vref1 = float(box_calibr_data['1V']) # from box cailbration data in CP2103 EEPROM
Vref2 = 0.4096 # reference voltage to set offset DAC
#---------------------------------------------------------------------------
# Measure 1
# Channel input = 0V, offset DAC = 0V
#---------------------------------------------------------------------------
print('\nMeasurement 1: channel input = 0V, offset DAC = 0V')
set_box_dac_range(box, fmc, 'AWG', 0.0, 'CAL_1V')
vm1 = []
for i in range(REPEAT):
vm1.append(channels_mean(spec_fmc, fmc, ADC_FS, False))
Vm1 = [mean([row[n] for row in vm1]) for n in range(NB_CHANNELS)]
for channel in range(1,NB_CHANNELS+1):
print('Channel %d: Vm1=%02.9fV')%(channel, Vm1[channel-1])
#---------------------------------------------------------------------------
# Measure 2
# Channel input = Vref = 0.4096V, offset DAC = 0V
#---------------------------------------------------------------------------
print('\nMeasurement 2: channel input = Vref = %1.8fV, offset DAC = 0V')%(Vref1)
set_box_dac_range(box, fmc, '1V', 0.0, '1V')
vm2 = []
for i in range(REPEAT):
vm2.append(channels_mean(spec_fmc, fmc, ADC_FS, False))
Vm2 = [mean([row[n] for row in vm2]) for n in range(NB_CHANNELS)]
for channel in range(1,NB_CHANNELS+1):
print('Channel %d: Vm2=%02.9fV')%(channel, Vm2[channel-1])
#---------------------------------------------------------------------------
# Measure 3
# Channel input = 0V, offset DAC = Vref = 0.4096V
#---------------------------------------------------------------------------
print('\nMeasurement 3: channel input = 0V, offset DAC = Vref = %1.8fV')%(Vref2)
set_box_dac_range(box, fmc, 'AWG', Vref2, 'CAL_1V')
vm3 = []
for i in range(REPEAT):
vm3.append(channels_mean(spec_fmc, fmc, ADC_FS, False))
Vm3 = [mean([row[n] for row in vm3]) for n in range(NB_CHANNELS)]
for channel in range(1,NB_CHANNELS+1):
print('Channel %d: Vm3=%02.9fV')%(channel, Vm3[channel-1])
#---------------------------------------------------------------------------
# Measure 4
# Channel input = Vref = 0.4096, offset DAC = Vref = 0.4096
#---------------------------------------------------------------------------
print('\nMeasurement 4: channel input = Vref = %1.8fV, offset DAC = Vref = %1.8fV')%(Vref1, Vref2)
set_box_dac_range(box, fmc, '1V', Vref2, '1V')
vm4 = []
for i in range(REPEAT):
vm4.append(channels_mean(spec_fmc, fmc, ADC_FS, False))
Vm4 = [mean([row[n] for row in vm4]) for n in range(NB_CHANNELS)]
for channel in range(1,NB_CHANNELS+1):
print('Channel %d: Vm4=%02.9fV')%(channel, Vm4[channel-1])
#---------------------------------------------------------------------------
# Calculate gain and offset parameters
# ga = ADC + input stage gain
# oa = ADC + input stage offset
# gd = DAC gain
# od = DAC offset
#---------------------------------------------------------------------------
print('\n1V range correction parameters\n----------------------------------')
ga = []
for channel in range(1,NB_CHANNELS+1):
ga.append(calc_ga(Vm1[channel-1], Vm2[channel-1], Vref1))
print('Channel %d ADC gain coeff: %02.9f')%(channel, ga[channel-1])
oa = []
for channel in range(1,NB_CHANNELS+1):
oa.append(calc_oa(Vm2[channel-1], Vm3[channel-1], Vm4[channel-1]))
print('Channel %d ADC offset : %02.9f')%(channel, oa[channel-1])
gd = []
for channel in range(1,NB_CHANNELS+1):
gd.append(calc_gd(Vm1[channel-1], Vm2[channel-1], Vm3[channel-1], Vref1, Vref2))
print('Channel %d DAC gain coeff: %02.9f')%(channel, gd[channel-1])
od = []
for channel in range(1,NB_CHANNELS+1):
od.append(calc_od(Vm1[channel-1], Vm2[channel-1], Vm3[channel-1], Vm4[channel-1], Vref1))
print('Channel %d DAC offset : %02.9f')%(channel, od[channel-1])
#---------------------------------------------------------------------------
# Calculate correction register values
#---------------------------------------------------------------------------
adc_corr_data[IN_RANGE]['offset'] = [-(volt2digital_without_offset(item,ADC_FS[IN_RANGE],ADC_NBITS)) for item in oa]
#-----------------------------------------------------------------------
# Calculate DAC correction register values
#-----------------------------------------------------------------------
# 0x8000 corresponds to 1.0
# Gain correction register is written with 1/gain * 1.0
adc_corr_data['1V']['gain'] = [int(round((1/item)*0x8000)) for item in ga]
dac_corr_data[IN_RANGE]['gain'] = [int(round((1/item)*0x8000)) for item in gd]
# oa is in volts and has to be converted to digital raw value,
# to be written in offset correction register
adc_corr_data['1V']['offset'] = [-(volt2digital_without_offset(item,ADC_FS,ADC_NBITS)) for item in oa]
dac_corr_data[IN_RANGE]['offset'] = [-(volt2digital_without_offset(item,DAC_FS,DAC_NBITS)) for item in od]
############################################################################
# 100mV range calibration
# Write ADC correction data tp file
############################################################################
out_filename = "test19_corr_data.txt"
f_out = open(out_filename, 'w')
print('\n100mV range calibration\n----------------------------------')
# ADC full scale is 100mV
ADC_FS = 0.1
# Reference voltage for calibration
Vref1 = float(box_calibr_data['100mV']) # from box cailbration data in CP2103 EEPROM
Vref2 = 0.04096 # reference voltage to set offset DAC
#---------------------------------------------------------------------------
# Measure 1
# Channel input = 0V, offset DAC = 0V
#---------------------------------------------------------------------------
print('\nMeasurement 1: channel input = 0V, offset DAC = 0V')
set_box_dac_range(box, fmc, 'AWG', 0.0, 'CAL_100mV')
vm1 = []
for i in range(REPEAT):
vm1.append(channels_mean(spec_fmc, fmc, ADC_FS, False))
Vm1 = [mean([row[n] for row in vm1]) for n in range(NB_CHANNELS)]
for channel in range(1,NB_CHANNELS+1):
print('Channel %d: Vm1=%02.9fV')%(channel, Vm1[channel-1])
#---------------------------------------------------------------------------
# Measure 2
# Channel input = Vref = 0.04096V, offset DAC = 0V
#---------------------------------------------------------------------------
print('\nMeasurement 2: channel input = Vref = %1.8fV, offset DAC = 0V')%(Vref1)
set_box_dac_range(box, fmc, '100mV', 0.0, '100mV')
vm2 = []
for i in range(REPEAT):
vm2.append(channels_mean(spec_fmc, fmc, ADC_FS, False))
Vm2 = [mean([row[n] for row in vm2]) for n in range(NB_CHANNELS)]
for channel in range(1,NB_CHANNELS+1):
print('Channel %d: Vm2=%02.9fV')%(channel, Vm2[channel-1])
#---------------------------------------------------------------------------
# Measure 3
# Channel input = 0V, offset DAC = Vref = 0.04096V
#---------------------------------------------------------------------------
print('\nMeasurement 3: channel input = 0V, offset DAC = Vref = %1.8fV')%(Vref2)
set_box_dac_range(box, fmc, 'AWG', Vref2, 'CAL_100mV')
vm3 = []
for i in range(REPEAT):
vm3.append(channels_mean(spec_fmc, fmc, ADC_FS, False))
Vm3 = [mean([row[n] for row in vm3]) for n in range(NB_CHANNELS)]
for channel in range(1,NB_CHANNELS+1):
print('Channel %d: Vm3=%02.9fV')%(channel, Vm3[channel-1])
#---------------------------------------------------------------------------
# Measure 4
# Channel input = Vref = 0.04096, offset DAC = Vref = 0.04096
#---------------------------------------------------------------------------
print('\nMeasurement 4: channel input = Vref = %1.8fV, offset DAC = Vref = %1.8fV')%(Vref1, Vref2)
set_box_dac_range(box, fmc, '100mV', Vref2, '100mV')
vm4 = []
for i in range(REPEAT):
vm4.append(channels_mean(spec_fmc, fmc, ADC_FS, False))
Vm4 = [mean([row[n] for row in vm4]) for n in range(NB_CHANNELS)]
for channel in range(1,NB_CHANNELS+1):
print('Channel %d: Vm4=%02.9fV')%(channel, Vm4[channel-1])
#---------------------------------------------------------------------------
# Calculate gain and offset parameters
# ga = ADC + input stage gain
# oa = ADC + input stage offset
# gd = DAC gain
# od = DAC offset
#---------------------------------------------------------------------------
print('\n100mV range correction parameters\n----------------------------------')
ga = []
for channel in range(1,NB_CHANNELS+1):
ga.append(calc_ga(Vm1[channel-1], Vm2[channel-1], Vref1))
print('Channel %d ADC gain coeff: %02.9f')%(channel, ga[channel-1])
oa = []
for channel in range(1,NB_CHANNELS+1):
oa.append(calc_oa(Vm2[channel-1], Vm3[channel-1], Vm4[channel-1]))
print('Channel %d ADC offset : %02.9f')%(channel, oa[channel-1])
gd = []
for channel in range(1,NB_CHANNELS+1):
gd.append(calc_gd(Vm1[channel-1], Vm2[channel-1], Vm3[channel-1], Vref1, Vref2))
print('Channel %d DAC gain coeff: %02.9f')%(channel, gd[channel-1])
od = []
for channel in range(1,NB_CHANNELS+1):
od.append(calc_od(Vm1[channel-1], Vm2[channel-1], Vm3[channel-1], Vm4[channel-1], Vref1))
print('Channel %d DAC offset : %02.9f')%(channel, od[channel-1])
#---------------------------------------------------------------------------
# Calculate correction register values
#---------------------------------------------------------------------------
# 0x8000 corresponds to 1.0
# Gain correction register is written with 1/gain * 1.0
adc_corr_data['100mV']['gain'] = [int(round((1/item)*0x8000)) for item in ga]
# oa is in volts and has to be converted to digital raw value,
# to be written in offset correction register
adc_corr_data['100mV']['offset'] = [-(volt2digital_without_offset(item,ADC_FS,ADC_NBITS)) for item in oa]
print "\nWrite ADC correction data to %s"%(out_filename)
for IN_RANGE in RANGES:
#print "%s range"%(IN_RANGE)
for item in adc_corr_data[IN_RANGE]['offset']:
#print '0x%.4X,yes'%(signed2hex(item))
f_out.write('0x%.4X,yes\n'%(signed2hex(item)))
for item in adc_corr_data[IN_RANGE]['gain']:
#print '0x%.4X,yes'%(signed2hex(item))
f_out.write('0x%.4X,yes\n'%(signed2hex(item)))
f_out.close()
############################################################################
# Write correction data tp file
# Write DAC correction data tp file
############################################################################
out_filename = "test19_corr_data.txt"
out_filename = "test19_dac_corr_data.txt"
f_out = open(out_filename, 'w')
# 10V range
print "10V range"
for item in adc_corr_data['10V']['offset']:
print '0x%.4X,yes'%(signed2hex(item))
f_out.write('0x%.4X,yes\n'%(signed2hex(item)))
for item in adc_corr_data['10V']['gain']:
print '0x%.4X,yes'%(signed2hex(item))
f_out.write('0x%.4X,yes\n'%(signed2hex(item)))
# 1V range
print "1V range"
for item in adc_corr_data['1V']['offset']:
print '0x%.4X,yes'%(signed2hex(item))
f_out.write('0x%.4X,yes\n'%(signed2hex(item)))
for item in adc_corr_data['1V']['gain']:
print '0x%.4X,yes'%(signed2hex(item))
f_out.write('0x%.4X,yes\n'%(signed2hex(item)))
# 100mV range
print "100mV range"
for item in adc_corr_data['100mV']['offset']:
print '0x%.4X,yes'%(signed2hex(item))
print "\nWrite DAC correction data to %s"%(out_filename)
for IN_RANGE in RANGES:
#print "%s range"%(IN_RANGE)
for item in dac_corr_data[IN_RANGE]['offset']:
#print '0x%.4X,yes'%(signed2hex(item))
f_out.write('0x%.4X,yes\n'%(signed2hex(item)))
for item in adc_corr_data['100mV']['gain']:
print '0x%.4X,yes'%(signed2hex(item))
for item in dac_corr_data[IN_RANGE]['gain']:
#print '0x%.4X,yes'%(signed2hex(item))
f_out.write('0x%.4X,yes\n'%(signed2hex(item)))
f_out.close()
"""
############################################################################
# Format FMC EEPROM data
############################################################################
......@@ -729,6 +473,7 @@ def main (default_directory = '.'):
if eeprom_content[i] != eeprom_content_read[i]:
print "[ERROR] eeprom data corruption @ addr:%d expect:0x%.2X read:0x%.2X"%(i, eeprom_content[i], eeprom_content_read[i])
"""
# Open all switches, reset offset DAC to mid-scale (0V)
for channel in range(1,NB_CHANNELS+1):
......@@ -740,8 +485,8 @@ def main (default_directory = '.'):
gen.close()
# Check if an error occured during frequency response test
#if(error != 0):
# raise PtsError('An error occured during frequency response test, check log for details.')
if(error != 0):
raise PtsError('An error occured during calibration, check log for details.')
if __name__ == '__main__' :
......
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