Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FMC ADC 100M 14b 4cha - Testing
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
FMC ADC 100M 14b 4cha - Testing
Commits
502308c9
Commit
502308c9
authored
Jan 11, 2012
by
Matthieu Cattin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Calibration validation in test20. In work.
parent
bd07c34e
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
441 additions
and
0 deletions
+441
-0
test20.py
test/fmcadc100m14b4cha/python/test20.py
+441
-0
No files found.
test/fmcadc100m14b4cha/python/test20.py
0 → 100644
View file @
502308c9
#! /usr/bin/env python
# coding: utf8
# Copyright CERN, 2011
# Author: Matthieu Cattin <matthieu.cattin@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
import
sys
import
rr
import
time
import
os
from
numpy
import
*
from
pylab
import
*
from
ctypes
import
*
from
ptsexcept
import
*
import
spec_fmc_adc
import
fmc_adc
import
calibr_box
import
find_usb_tty
import
cp210x_eeprom
from
PAGE.Agilent33250A
import
*
from
PAGE.SineWaveform
import
*
"""
test20: Calibration verification
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
NB_CHANNELS
=
4
AWG_SET_SLEEP
=
1
SSR_SET_SLEEP
=
0.05
BOX_SET_SLEEP
=
1
DAC_SET_SLEEP
=
0.1
ACQ_TIMEOUT
=
10
MAX_FIRMWARE_RELOAD
=
10
PRE_TRIG_SAMPLES
=
1000
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
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
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
disconnect_channels
(
fmc
)
# Reset offset DACs
fmc
.
dc_offset_reset
()
# Set trigger
fmc
.
set_soft_trig
()
# Set acquisition
fmc
.
set_pre_trig_samples
(
PRE_TRIG_SAMPLES
)
fmc
.
set_post_trig_samples
(
POST_TRIG_SAMPLES
)
fmc
.
set_shots
(
NB_SHOTS
)
# 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
):
return
-
((
~
value
&
0xFFFF
)
+
1
)
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
):
digital
=
(
value
)
*
2
**
nb_bit
/
full_scale
if
(
digital
>
2
**
nb_bit
-
1
):
digital
=
~
(
1
<<
nb_bit
)
if
(
digital
<
0
):
digital
=
(
1
<<
nb_bit
)
#print('volt2digital: %2.9f > %2.9f')%(value,digital)
return
int
(
digital
)
def
set_offset_dac
(
fmc
,
dac_fs
,
dac_nbits
,
channel
,
offset_volt
,
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)
if
(
True
==
dac_corr_flag
):
fmc
.
set_dc_offset_corrected
(
channel
,
dac_d
)
else
:
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
)
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
)
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.9
fV'
)
%
(
channel
,
mean_v
[
channel
-
1
])
if
(
True
==
plot_flag
):
plot_all
(
acq_v
,
mean_v
,
ADC_FS
/
2.0
)
return
mean_v
# Calculates ADC + input stage gain
def
calc_ga
(
Vm1
,
Vm2
,
Vref1
):
return
((
Vm2
-
Vm1
)
/
Vref1
)
# Calculates ADC + input stage offset
def
calc_oa
(
Vm2
,
Vm3
,
Vm4
):
return
(
Vm2
+
Vm3
-
Vm4
)
# Calculates DAC gain
def
calc_gd
(
Vm1
,
Vm2
,
Vm3
,
Vref1
,
Vref2
):
return
((
Vref1
*
(
Vm3
-
Vm1
))
/
(
Vref2
*
(
Vm1
-
Vm2
)))
# Calculates DAC offset
def
calc_od
(
Vm1
,
Vm2
,
Vm3
,
Vm4
,
Vref1
):
return
((
Vref1
*
(
Vm1
-
Vm2
-
Vm3
+
Vm4
))
/
(
Vm1
-
Vm2
))
def
main
(
default_directory
=
'.'
):
# Load firmware to FPGA
load_firmware
(
default_directory
)
# Objects declaration
spec
=
rr
.
Gennum
()
# bind to the SPEC board
spec_fmc
=
spec_fmc_adc
.
CSpecFmcAdc100Ms
(
spec
)
fmc
=
fmc_adc
.
CFmcAdc100Ms
(
spec
)
usb_tty
=
find_usb_tty
.
CttyUSB
()
awg_tty
=
usb_tty
.
find_usb_tty
(
AWG_USB_VENDOR_ID
,
AWG_USB_PRODUCT_ID
)
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
)
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
)
# Connect to AWG
gen
.
connect
()
# Switch AWG output OFF
gen
.
output
=
False
# Measure FMC and carrier temperature
print
(
'SPEC temperature:
%3.3
f°C'
)
%
spec_fmc
.
get_temp
()
print
(
'FMC temperature :
%3.3
f°C'
)
%
fmc
.
get_temp
()
# Open all switches, reset offset DAC to mid-scale (0V)
for
channel
in
range
(
1
,
NB_CHANNELS
+
1
):
fmc
.
set_input_range
(
channel
,
'OPEN'
)
fmc
.
set_input_term
(
channel
,
'OFF'
)
fmc
.
dc_offset_reset
()
#---------------------------------------------------------------------------
# Write DAC gain and offset corerection value to fmc class
#---------------------------------------------------------------------------
print
(
'
\n
Apply DAC correction
\n
----------------------------------'
)
print
(
'DACs are precise enough.
\n
Do not apply any correction.'
)
"""
dac_gain_corr = [1/item for item in gd]
dac_offset_corr = [-item for item in od]
fmc.set_dac_corr(dac_gain_corr, dac_offset_corr)
for channel in range(1,NB_CHANNELS+1):
print('CH
%
d DAC offset correction:
%1.9
f')
%
(channel,dac_offset_corr[channel-1])
print('CH
%
d DAC gain correction :
%1.9
f')
%
(channel,dac_gain_corr[channel-1])
#---------------------------------------------------------------------------
# Test
#---------------------------------------------------------------------------
print('
\n
Channel input = 0V, offset DAC = 0V
\n
----------------------------------')
#raw_input('...')
set_box_dac_range(box, fmc, 'AWG', 0.0, 'CAL_100mV', True)
mean_v = channels_mean(spec_fmc, fmc, ADC_FS, True)
#plot_all(acq_v, mean_v, ADC_FS/2.0)
"""
#---------------------------------------------------------------------------
# Write ADC + input stage gain and offset correction to hardware
#---------------------------------------------------------------------------
print
(
'
\n
Apply ADC offset correction
\n
----------------------------------'
)
#fmc.print_adc_core_config()
#adc_gain_corr = [int(round((1/item)*0x8000)) for item in ga]
adc_gain_corr
=
[
0x8000
]
*
4
adc_offset_corr
=
[
-
(
volt2digital_without_offset
(
item
,
ADC_FS
,
ADC_NBITS
))
for
item
in
oa
]
#adc_offset_corr = [0] * 4
for
channel
in
range
(
1
,
NB_CHANNELS
+
1
):
fmc
.
set_adc_gain_offset_corr
(
channel
,
adc_gain_corr
[
channel
-
1
],
adc_offset_corr
[
channel
-
1
])
#fmc.print_adc_core_config()
for
channel
in
range
(
1
,
NB_CHANNELS
+
1
):
print
(
'CH
%
d ADC offset correction write:0x
%.8
X read:0x
%.8
X'
)
%
(
channel
,
adc_offset_corr
[
channel
-
1
],
fmc
.
get_adc_offset_corr
(
channel
))
print
(
'CH
%
d ADC gain correction write:0x
%.8
X read:0x
%.8
X'
)
%
(
channel
,
adc_gain_corr
[
channel
-
1
],
fmc
.
get_adc_gain_corr
(
channel
))
#---------------------------------------------------------------------------
# Test
#---------------------------------------------------------------------------
print
(
'
\n
Channel input = 0V, offset DAC = 0V
\n
----------------------------------'
)
#raw_input('...')
set_box_dac_range
(
box
,
fmc
,
'AWG'
,
0.0
,
'CAL_100mV'
,
True
)
mean_v
=
channels_mean
(
spec_fmc
,
fmc
,
ADC_FS
,
True
)
#---------------------------------------------------------------------------
# Write ADC + input stage gain and offset correction to hardware
#---------------------------------------------------------------------------
print
(
'
\n
Apply ADC gain correction
\n
----------------------------------'
)
#fmc.print_adc_core_config()
adc_gain_corr
=
[
int
(
round
((
1
/
item
)
*
0x8000
))
for
item
in
ga
]
#adc_gain_corr = [0x8000] * 4
adc_offset_corr
=
[
-
(
volt2digital_without_offset
(
item
,
ADC_FS
,
ADC_NBITS
))
for
item
in
oa
]
#adc_offset_corr = [0] * 4
for
channel
in
range
(
1
,
NB_CHANNELS
+
1
):
fmc
.
set_adc_gain_offset_corr
(
channel
,
adc_gain_corr
[
channel
-
1
],
adc_offset_corr
[
channel
-
1
])
#fmc.print_adc_core_config()
for
channel
in
range
(
1
,
NB_CHANNELS
+
1
):
print
(
'CH
%
d ADC offset correction write:0x
%.8
X read:0x
%.8
X'
)
%
(
channel
,
adc_offset_corr
[
channel
-
1
],
fmc
.
get_adc_offset_corr
(
channel
))
print
(
'CH
%
d ADC gain correction write:0x
%.8
X read:0x
%.8
X'
)
%
(
channel
,
adc_gain_corr
[
channel
-
1
],
fmc
.
get_adc_gain_corr
(
channel
))
#---------------------------------------------------------------------------
# Test
#---------------------------------------------------------------------------
print
(
'
\n
Channel input = 0V, offset DAC = 0V
\n
----------------------------------'
)
#raw_input('...')
set_box_dac_range
(
box
,
fmc
,
'AWG'
,
0.0
,
'CAL_100mV'
,
True
)
mean_v
=
channels_mean
(
spec_fmc
,
fmc
,
ADC_FS
,
True
)
#---------------------------------------------------------------------------
# Test
#---------------------------------------------------------------------------
print
(
'
\n
Channel input = 0V, offset DAC = Vref = 0.04096V
\n
----------------------------------'
)
#raw_input('...')
set_box_dac_range
(
box
,
fmc
,
'AWG'
,
0.04096
,
'CAL_100mV'
,
True
)
mean_v
=
channels_mean
(
spec_fmc
,
fmc
,
ADC_FS
,
True
)
#---------------------------------------------------------------------------
# Test
#---------------------------------------------------------------------------
print
(
'
\n
Channel input = 0V, offset DAC = -Vref = -0.04096V
\n
----------------------------------'
)
#raw_input('...')
set_box_dac_range
(
box
,
fmc
,
'AWG'
,
-
0.04096
,
'CAL_100mV'
,
True
)
mean_v
=
channels_mean
(
spec_fmc
,
fmc
,
ADC_FS
,
True
)
#---------------------------------------------------------------------------
# Test
#---------------------------------------------------------------------------
print
(
'
\n
Channel input = Vref = 0.04096V, offset DAC = 0V
\n
----------------------------------'
)
#raw_input('...')
set_box_dac_range
(
box
,
fmc
,
'100mV'
,
0.0
,
'100mV'
,
True
)
mean_v
=
channels_mean
(
spec_fmc
,
fmc
,
ADC_FS
,
True
)
# Open all switches, reset offset DAC to mid-scale (0V)
for
channel
in
range
(
1
,
NB_CHANNELS
+
1
):
fmc
.
set_input_range
(
channel
,
'OPEN'
)
fmc
.
set_input_term
(
channel
,
'OFF'
)
fmc
.
dc_offset_reset
()
# Close AWG
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
__name__
==
'__main__'
:
main
()
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment