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
b8629c15
Commit
b8629c15
authored
Jan 26, 2012
by
Matthieu Cattin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use new DMA acquisition function from spec_fmc, frequency response in dB, use calibration box v2.
parent
30f3d392
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
159 additions
and
174 deletions
+159
-174
test09.py
test/fmcadc100m14b4cha/python/test09.py
+159
-174
No files found.
test/fmcadc100m14b4cha/python/test09.py
View file @
b8629c15
...
...
@@ -15,284 +15,269 @@ from pylab import *
from
ptsexcept
import
*
import
gn4124
import
spec_fmc_adc
import
fmc_adc
import
calibr_box
import
find_usb_tty
from
PAGE.Agilent33250A
import
*
from
PAGE.SineWaveform
import
*
"""
test09: Test analogue front-end frequency response
test09: Test analogue front-end frequency response,
with limits check
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
AWG_BAUD
=
57600
USB_DEVICE
=
"/dev/ttyUSB0"
RS232_BAUD
=
57600
NB_CHANNELS
=
4
AWG_SET_SLEEP
=
1
AWG_SET_SLEEP
=
0.6
SSR_SET_SLEEP
=
0.05
BOX_SET_SLEEP
=
1
ACQ_TIMEOUT
=
10
MAX_FIRMWARE_RELOAD
=
10
PRE_TRIG_SAMPLES
=
1000
POST_TRIG_SAMPLES
=
1000
PRE_TRIG_SAMPLES
=
10
POST_TRIG_SAMPLES
=
10000
NB_SHOTS
=
1
DMA_LENGTH
=
4096
# DMA length in byt
es
ACQ_LENGTH
=
10000
# in sampl
es
# col 0: freq
# col 1: expected amplitude (ADC raw data)
# col 2: tolerance on the amplitude
points
=
[[
1E6
,
33300
,
4000
],
[
10E6
,
21000
,
4000
],
[
15E6
,
16500
,
4000
],
[
16E6
,
15700
,
4000
],
[
17E6
,
15000
,
4000
],
[
18E6
,
14500
,
4000
],
[
19E6
,
14000
,
4000
],
[
20E6
,
12500
,
4000
],
[
21E6
,
12500
,
4000
],
[
22E6
,
12500
,
4000
],
[
23E6
,
12000
,
4000
],
[
24E6
,
11500
,
4000
],
[
25E6
,
10000
,
4000
],
[
30E6
,
9000
,
4000
],
[
40E6
,
4500
,
4000
],
[
60E6
,
1000
,
700
],
[
80E6
,
400
,
300
]]
# The following table is used to test the test
"""
points = [[1E6, 36300, 1000],
[10E6, 24000, 1000],
[15E6, 19500, 1000],
[16E6, 18700, 1000],
[17E6, 18000, 1000],
[18E6, 17500, 1000],
[19E6, 17000, 1000],
[20E6, 15500, 1000],
[21E6, 15500, 1000],
[22E6, 15500, 1000],
[23E6, 15000, 1000],
[24E6, 14500, 1000],
[25E6, 14000, 2000],
[30E6, 12000, 1000],
[40E6, 7500, 1000],
[60E6, 4000, 500],
[80E6, 3400, 200]]
"""
# col 1: expected attenuation (in dB)
# col 2: tolerance on attenuation (in dB)
points
=
[[
10E3
,
0
,
1
],
[
100E3
,
0
,
1
],
[
1E6
,
0
,
1
],
[
5E6
,
0
,
1
],
[
10E6
,
0
,
1
],
[
12E6
,
0
,
1
],
[
14E6
,
0
,
1
],
[
16E6
,
0
,
2
],
[
18E6
,
0
,
2
],
[
20E6
,
0
,
2
],
[
22E6
,
0
,
2
],
[
24E6
,
-
0.5
,
2
],
[
26E6
,
-
1
,
2
],
[
28E6
,
-
2
,
2
],
[
30E6
,
-
3.5
,
2
],
[
32E6
,
-
4.5
,
2
],
[
34E6
,
-
6.5
,
2
],
[
36E6
,
-
8.5
,
2
],
[
38E6
,
-
10.5
,
2
],
[
40E6
,
-
13.5
,
2
],
[
42E6
,
-
15
,
2
],
[
44E6
,
-
17.5
,
2
],
[
46E6
,
-
20
,
2
],
[
48E6
,
-
22.5
,
2
],
[
60E6
,
-
38
,
3
],
[
80E6
,
-
66
,
3
]]
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
open_all_channels
(
fmc
):
for
i
in
range
(
1
,
NB_CHANNELS
+
1
):
fmc
.
set_input_range
(
i
,
'OPEN'
)
time
.
sleep
(
SSR_SET_SLEEP
)
def
fmc_adc_init
(
spec
,
fmc
):
print
(
'Initialise FMC board.'
)
fmc
.
__init__
(
spec
)
print
"Initialise FMC board."
# Reset offset DACs
fmc
.
dc_offset_reset
()
# Make sure all switches are OFF
open_all_channels
(
fmc
)
# Set trigger
# hw trig, rising edge, external, sw disable, no delay
fmc
.
set_trig_config
(
1
,
0
,
1
,
1
,
0
,
0
,
0
)
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
()
#fmc.print_adc_core_config()
def
set_awg_freq
(
gen
,
sine
,
freq
):
sine
.
frequency
=
freq
gen
.
play
(
sine
)
print
(
'Sine frequency:
%3.3
fMHz'
)
%
(
sine
.
frequency
/
1E6
)
#
print('Sine frequency:%3.3fMHz')%(sine.frequency/1E6)
time
.
sleep
(
AWG_SET_SLEEP
)
# Converts two's complement hex to signed
def
hex2signed
(
value
):
if
(
value
&
0x8000
):
return
-
((
~
value
&
0xFFFF
)
+
1
)
else
:
return
value
def
acquisition
(
gnum
,
pages
,
fmc
,
channel_nb
,
channel_data
):
# Start acquisition
# Converts digital value to volts
def
digital2volt
(
value
,
full_scale
,
nb_bit
):
return
float
(
value
)
*
float
(
full_scale
)
/
2
**
nb_bit
def
acq_channels
(
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.'
)
print
"Acquisition timeout. Missing trigger?."
print
"Acq FSm state:
%
s"
%
fmc
.
get_acq_fsm_state
()
return
1
#raise PtsError('Acquisition timeout. Check that the AWG is switched ON and properly connected.')
# Retrieve data trough DMA
page1_data_before_dma
=
gnum
.
get_memory_page
(
1
)
gnum
.
add_dma_item
(
0x100
,
pages
[
1
],
DMA_LENGTH
,
0
,
0
)
gnum
.
start_dma
()
gnum
.
wait_irq
()
page1_data
=
gnum
.
get_memory_page
(
1
)
page_zeros
=
[
0
]
*
len
(
page1_data
)
if
((
page1_data_before_dma
==
page1_data
)
or
(
page_zeros
==
page1_data
)):
print
(
'Previous page:'
)
print
page1_data_before_dma
[
0
:
20
]
print
(
'Current page:'
)
print
page1_data
[
0
:
20
]
print
(
'### Acquisition or DMA error. ###'
)
#raise PtsWarning('Acquisition or DMA error.')
return
1
for
i
in
range
(
len
(
page1_data
)):
channel_data
.
append
(
page1_data
[
i
]
&
0xFFFF
)
channel_data
.
append
(
page1_data
[
i
]
>>
16
)
channel_data
=
channel_data
[
channel_nb
-
1
::
4
]
return
0
def
show_result_graph
(
points
,
ch_diff
):
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
,
1.0
,
16
)
for
item
in
channels_data
]
return
channels_data
def
show_result_graph
(
points
,
ch_att
):
pt
=
array
(
points
)
freq
=
pt
[:,
0
]
a_min
=
pt
[:,
1
]
-
pt
[:,
2
]
a_max
=
pt
[:,
1
]
+
pt
[:,
2
]
semilogx
(
freq
,
ch_diff
[
0
::
4
],
'b'
,
label
=
'Channel 1'
)
semilogx
(
freq
,
ch_diff
[
1
::
4
],
'g'
,
label
=
'Channel 2'
)
semilogx
(
freq
,
ch_diff
[
2
::
4
],
'r'
,
label
=
'Channel 3'
)
semilogx
(
freq
,
ch_diff
[
3
::
4
],
'c'
,
label
=
'Channel 4'
)
cutoff
=
[
-
3
]
*
len
(
points
)
semilogx
(
freq
,
ch_att
[
0
],
'b'
,
label
=
'Channel 1'
)
semilogx
(
freq
,
ch_att
[
1
],
'g'
,
label
=
'Channel 2'
)
semilogx
(
freq
,
ch_att
[
2
],
'm'
,
label
=
'Channel 3'
)
semilogx
(
freq
,
ch_att
[
3
],
'c'
,
label
=
'Channel 4'
)
semilogx
(
freq
,
a_min
,
'r:'
,
label
=
'Lower limit'
)
semilogx
(
freq
,
a_max
,
'r:'
,
label
=
'Upper limit'
)
legend
()
semilogx
(
freq
,
cutoff
,
'k'
,
label
=
'-3dB'
)
grid
(
color
=
'k'
,
linestyle
=
'--'
,
linewidth
=
1
)
legend
(
loc
=
'upper left'
)
show
()
return
0
def
main
(
default_directory
=
'.'
):
"""
# Load firmware to FPGA
path_fpga_loader = '../../../gnurabbit/user/fpga_loader';
path_firmware = '../firmwares/spec_fmcadc100m14b4cha.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);
"""
# Load firmware
load_firmware
(
default_directory
)
# Objects declaration
spec
=
rr
.
Gennum
()
# bind to the SPEC board
gnum
=
gn4124
.
CGN4124
(
spec
,
GN4124_CSR
)
spec_fmc
=
spec_fmc_adc
.
CSpecFmcAdc100Ms
(
spec
)
fmc
=
fmc_adc
.
CFmcAdc100Ms
(
spec
)
gen
=
Agilent33250A
(
device
=
USB_DEVICE
,
bauds
=
RS232_BAUD
)
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
)
gen
=
Agilent33250A
(
device
=
awg_tty
[
0
],
bauds
=
AWG_BAUD
)
sine
=
SineWaveform
()
# Enable "DMA finished" IRQ
spec_fmc
.
set_irq_en_mask
(
0x1
)
box
=
calibr_box
.
CCalibr_box
(
box_tty
[
0
])
# Initialise fmc adc
fmc_adc_init
(
spec
,
fmc
)
# Set sine params
sine
.
frequency
=
1E6
sine
.
amplitude
=
0.
25
sine
.
amplitude
=
0.
8
sine
.
dc
=
0
print
(
'Sine frequency:
%3.3
fMHz amplitude:
%2.3
fVp offset:
%2.3
fV'
)
%
(
sine
.
frequency
/
1E6
,
sine
.
amplitude
,
sine
.
dc
)
#
print('Sine frequency:%3.3fMHz amplitude:%2.3fVp offset:%2.3fV')%(sine.frequency/1E6, sine.amplitude, sine.dc)
# Set AWG
gen
.
connect
()
gen
.
play
(
sine
)
gen
.
output
=
True
# Get physical addresses of the pages for DMA transfer
pages
=
gnum
.
get_physical_addr
()
# Test frequency response of all channels
ch_diff
=
[]
j
=
0
retry_cnt
=
0
error
=
0
while
(
j
<
len
(
points
)):
#print('begin loop j=%d')%(j
)
set_awg_freq
(
gen
,
sine
,
points
[
j
][
0
])
for
i
in
range
(
1
,
NB_CHANNELS
+
1
):
fmc
.
set_input_range
(
i
,
'1V'
)
time
.
sleep
(
SSR_SET_SLEEP
)
print
"
\n
Frequency response measurement."
ch_ampl
=
[[],[],[],[]]
for
i
in
range
(
1
,
NB_CHANNELS
+
1
):
fmc
.
set_input_range
(
i
,
'1V'
)
fmc
.
set_input_term
(
i
,
'ON'
)
time
.
sleep
(
SSR_SET_SLEEP
)
box
.
select_output_ch
(
i
)
# connect AWG to current channel
time
.
sleep
(
BOX_SET_SLEEP
)
for
j
in
range
(
len
(
points
)):
set_awg_freq
(
gen
,
sine
,
points
[
j
][
0
]
)
channel_data
=
[]
retry
=
acquisition
(
gnum
,
pages
,
fmc
,
i
,
channel_data
)
if
(
retry
!=
0
):
retry_cnt
+=
1
print
(
'RETRY:
%
d'
)
%
(
retry_cnt
)
if
(
MAX_FIRMWARE_RELOAD
<
retry_cnt
):
print
(
'Maximium of
%
d retry exceeded (channel:
%
d, freq:
%2.3
fMHz)'
)
%
(
MAX_FIRMWARE_RELOAD
,
i
,
points
[
j
][
0
]
/
1E6
)
error
+=
1
break
#raise PtsError('Maximium of %d retry exceeded (channel:%d, freq:%2.3fMHz)'%(MAX_FIRMWARE_RELOAD, i, points[j][0]/1E6))
load_firmware
(
default_directory
)
fmc_adc_init
(
spec
,
fmc
)
#time.sleep(2)
break
diff
=
max
(
channel_data
)
-
min
(
channel_data
)
print
(
'CH
%
d amplitude:
%
d expected:
%
d +/-
%
d'
)
%
(
i
,
diff
,
points
[
j
][
1
],
points
[
j
][
2
])
ch_diff
.
append
(
diff
)
fmc
.
set_input_range
(
i
,
'OPEN'
)
if
((
diff
<
points
[
j
][
1
]
-
points
[
j
][
2
])
|
(
diff
>
points
[
j
][
1
]
+
points
[
j
][
2
])):
print
(
'Channel
%
d frequency response is out of range at freq:
%2.3
fMHz'
)
%
(
i
,
points
[
j
][
0
]
/
1E6
)
print
(
'Current amplitude:
%
d, expected:
%
d +/-
%
d'
)
%
(
diff
,
points
[
j
][
1
],
points
[
j
][
2
])
channels_data
=
acq_channels
(
fmc
,
spec_fmc
)
channel_data
=
channels_data
[
i
-
1
::
4
]
ampl
=
max
(
channel_data
)
-
min
(
channel_data
)
print
"CH
%
d frequency:
%8.0
f Hz amplitude:
%
f V"
%
(
i
,
points
[
j
][
0
],
ampl
)
ch_ampl
[
i
-
1
]
.
append
(
ampl
)
fmc
.
set_input_range
(
i
,
'OPEN'
)
fmc
.
set_input_term
(
i
,
'OFF'
)
# Convert volts to dB
ch_att
=
[[],[],[],[]]
for
ch
in
range
(
NB_CHANNELS
):
vref
=
ch_ampl
[
ch
][
0
]
print
"Channel
%
d vref=
%
f"
%
(
ch
,
vref
)
ch_att
[
ch
]
=
[(
20
*
log
(
item
/
vref
))
for
item
in
ch_ampl
[
ch
]]
# Check that frequency response is in the limits
print
"
\n
Frequency response check."
error
=
0
for
i
in
range
(
len
(
points
)):
for
ch
in
range
(
NB_CHANNELS
):
if
((
ch_att
[
ch
][
i
]
<
points
[
j
][
1
]
-
points
[
j
][
2
])
|
(
ch_att
[
ch
][
i
]
>
points
[
i
][
1
]
+
points
[
i
][
2
])):
print
"Channel
%
d frequency response is out of range at freq:
%2.3
fMHz"
%
(
ch
+
1
,
points
[
i
][
0
]
/
1E6
)
print
"Attenuation:
%3.3
fdB, expected:
%2.1
f +/-
%2.1
fdB"
%
(
ch_att
[
ch
][
i
],
points
[
i
][
1
],
points
[
i
][
2
])
error
+=
1
#raise PtsError('Channel %d frequency response is out of range at freq:%2.3fMHz'%(i, points[j][0]/1E6))
if
(
retry
==
0
):
j
+=
1
retry_cnt
=
0
#print('j++')
#print('end loop j=%d')%(j)
if
error
==
0
:
print
"OK!"
# print freqency response to log
print
(
'
Channels frequency response
'
)
print
(
'Frequency, Expected value, tolerance, CH1
value, CH2 value, CH3 value, CH4 value
'
)
print
(
'
\n
Channels frequency response in dB
'
)
print
(
'Frequency, Expected value, tolerance, CH1
attenuation, CH2 attenuation, CH3 attenuation, CH4 attenuation, Mean attenuation
'
)
for
i
in
range
(
len
(
points
)):
print
(
'
%2.3
f,
%
d,
%
d,
%
d,
%
d,
%
d,
%
d'
)
%
(
points
[
i
][
0
]
/
1E6
,
points
[
i
][
1
],
points
[
i
][
2
],
ch_diff
[
i
*
4
],
ch_diff
[
i
*
4
+
1
],
ch_diff
[
i
*
4
+
2
],
ch_diff
[
i
*
4
+
3
])
# The following code is to show a graph of the test results
# !! Don't forget to import numpy and pylab !!
"""
pt = array(points)
freq = pt[:,0]
a_min = pt[:,1] - pt[:,2]
a_max = pt[:,1] + pt[:,2]
semilogx(freq, ch_diff[0::4], 'b', label='Channel 1')
semilogx(freq, ch_diff[1::4], 'g', label='Channel 2')
semilogx(freq, ch_diff[2::4], 'r', label='Channel 3')
semilogx(freq, ch_diff[3::4], 'c', label='Channel 4')
semilogx(freq, a_min, 'r:', label='Lower limit')
semilogx(freq, a_max, 'r:', label='Upper limit')
legend()
show()
"""
ch_att_mean
=
(
ch_att
[
0
][
i
]
+
ch_att
[
1
][
i
]
+
ch_att
[
2
][
i
]
+
ch_att
[
3
][
i
])
/
4
print
"
%8.0
f,
%3
d,
%2
d,
% 3.3
f,
% 3.3
f,
% 3.3
f,
% 3.3
f,
%
f"
%
(
points
[
i
][
0
],
points
[
i
][
1
],
points
[
i
][
2
],
ch_att
[
0
][
i
],
ch_att
[
1
][
i
],
ch_att
[
2
][
i
],
ch_att
[
3
][
i
],
ch_att_mean
)
# print frequency response to a separate file
file_name
=
"test09_freq_resp.txt"
f
=
open
(
file_name
,
'w'
)
for
i
in
range
(
len
(
points
)):
f
.
write
(
'
%8.0
f,
%2.1
f,
%2.1
f,
% 3.3
f,
% 3.3
f,
% 3.3
f,
% 3.3
f
\n
'
%
(
points
[
i
][
0
],
points
[
i
][
1
],
points
[
i
][
2
],
ch_att
[
0
][
i
],
ch_att
[
1
][
i
],
ch_att
[
2
][
i
],
ch_att
[
3
][
i
]))
f
.
close
()
# Plot results -> use test10.py to plot the results!
#show_result_graph(points, ch_att)
# Make sure all switches are OFF
open_all_channels
(
fmc
)
...
...
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