Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FMC DEL 1ns 2cha
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
9
Issues
9
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 DEL 1ns 2cha
Commits
857483c0
Commit
857483c0
authored
Sep 14, 2017
by
Jan Pospisil
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added test script; reformatted Ffpg class (added comments)
parent
6e97c2da
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
366 additions
and
182 deletions
+366
-182
readme.txt
readme.txt
+1
-1
FFPG_test.py
sw/FFPG_test.py
+166
-0
Ffpg.py
sw/Ffpg.py
+199
-181
No files found.
readme.txt
View file @
857483c0
...
...
@@ -31,7 +31,7 @@ The "!->" determines what to check further when check fails.
1) Plug FMC mezzanine into SVEC carrier board and into VME crate (and configure properly)
2) When using FMC mezzanine version 2 (EDA-03339-V2), check that all power LEDs (LD1, LD2, LD3) are on (!-> SVEC fuses, power supplies)
3) Connect clock (CLK IN) f_CLK = 400.789 MHz and trigger (TRIG IN) f_TRIG = 11.245 kHz - trigger has to be phase aligned with clock
4) Use /sw/FFPG_driver.py to configure the GW and run some test
4) Use /sw/FFPG_driver.py
or /sw/FFPG_test.py
to configure the GW and run some test
5) Check:
a) There is f_CLK/2 clock present on CLK OUT (!-> AD9512 divider)
b) LED CLK IN is on (!-> clock source is not stable?)
...
...
sw/FFPG_test.py
0 → 100644
View file @
857483c0
#!/usr/bin/env python
# coding: utf8
##-----------------------------------------------------------------------------
## Title : Test Script
## Project : FMC DEL 1ns 2cha (FFPG)
## URL : http://www.ohwr.org/projects/fmc-del-1ns-2cha
##-----------------------------------------------------------------------------
## File : FFPG_test.py
## Author(s) : Jan Pospisil <j.pospisil@cern.ch>
## Company : CERN (BE-BI-QP)
## Created : 2017-09-14
## Last update: 2017-09-14
## Standard : Python
##-----------------------------------------------------------------------------
## Description: Script for testing new boards
##-----------------------------------------------------------------------------
## Copyright (c) 2017 CERN (BE-BI-QP)
##-----------------------------------------------------------------------------
## GNU LESSER GENERAL PUBLIC LICENSE
##-----------------------------------------------------------------------------
## This source file is free software; you can redistribute it and/or modify it
## under the terms of the GNU Lesser General Public License as published by the
## Free Software Foundation; either version 2.1 of the License, or (at your
## option) any later version. This source is distributed in the hope that it
## will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
## of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
## See the GNU Lesser General Public License for more details. You should have
## received a copy of the GNU Lesser General Public License along with this
## source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
##-----------------------------------------------------------------------------
## Revisions :
## Date Version Author Comment
## 2017-09-14 1.0 Jan Pospisil Created (based on FFPG_driver)
##-----------------------------------------------------------------------------
import
time
import
sys
from
Ffpg
import
*
calibrationData
=
[
# -1 = uncalibrated
# channel 1, channel 2
[
-
1
,
-
1
],
# FMC slot 0
[
-
1
,
-
1
]
# FMC slot 1
]
def
Init
(
pg
):
global
calibrationData
pg
.
Reset
()
pg
.
SelectClock
(
"external"
,
400.789
)
pg
.
SetRatio
(
2
)
pg
.
SetOverflow
(
17820
)
pg
.
Ad9512Sync
()
pg
.
SetTriggerThreshold
(
0.5
)
pg
.
SetVcxoFrequency
(
-
0.2105
)
# 125.0000 MHz
# calibration
fmcSlot
=
pg
.
GetFmcSlot
()
for
channel
in
[
1
,
2
]:
triggerPhase
=
calibrationData
[
fmcSlot
][
channel
-
1
]
print
(
"Calibrating channel "
+
str
(
channel
)
+
" on FMC slot "
+
str
(
fmcSlot
)
+
" to "
+
str
(
triggerPhase
)
+
" ns"
)
if
triggerPhase
>
-
1
:
pg
.
SetTriggerPhase
(
channel
,
triggerPhase
)
else
:
print
(
" (Skipping this calibration, no calibration data (-1) provided.)"
)
def
TestSinglePulse
(
pg
,
channel
,
start
,
width
,
polarity
):
pg
.
ResetBadState
(
channel
)
pg
.
CreateSinglePulse
(
channel
,
start
,
width
,
polarity
)
pg
.
EnableChannel
(
channel
)
pg
.
StartChannel
(
channel
)
def
StopAndDisable
(
pg
,
channel
):
pg
.
StopChannel
(
channel
)
pg
.
DisableChannel
(
channel
)
def
PrintFrequency
(
pg
):
frequency
=
pg
.
GetFrequency
()
if
frequency
is
not
None
:
print
(
"RF clock frequency: "
+
str
(
frequency
/
1.0e6
)
+
" MHz"
)
else
:
print
(
"RF clock frequency: (unstable)"
)
def
StrPolarity
(
polarity
):
if
polarity
==
1
:
return
"positive polarity"
elif
polarity
==
0
:
return
"negative polarity"
else
:
return
"unknown polarity"
while
True
:
fmcSlot
=
-
1
while
(
fmcSlot
<
0
)
or
(
fmcSlot
>
1
):
try
:
fmcSlot
=
int
(
raw_input
(
"Enter FMC slot to test (0 - lower FMC1, 1 - upper FMC2): "
))
except
KeyboardInterrupt
:
print
""
sys
.
exit
()
except
:
fmcSlot
=
-
1
channel
=
-
1
while
(
channel
<
1
)
or
(
channel
>
2
):
try
:
channel
=
int
(
raw_input
(
"Enter channel number to test (1, 2): "
))
except
KeyboardInterrupt
:
print
""
sys
.
exit
()
except
:
channel
=
-
1
# create FFPG driver for FMC slot
pg
=
Ffpg
(
fmcSlot
)
# initialize the driver
Init
(
pg
)
# test LEDs
pg
.
LedModeTest
()
raw_input
(
"All LEDs should be blinking... (press Enter)"
)
pg
.
LedModeNormal
()
# test pulses
start
=
10
width
=
10
polarity
=
1
TestSinglePulse
(
pg
,
channel
,
start
,
width
,
polarity
)
raw_input
(
"Basic pulse generated (start = "
+
str
(
start
)
+
" ns, width = "
+
str
(
width
)
+
" ns, "
+
StrPolarity
(
polarity
)
+
") (press Enter)"
)
for
start
in
range
(
10
,
13
+
1
):
TestSinglePulse
(
pg
,
channel
,
start
,
width
,
polarity
)
raw_input
(
"Shifting start of the pulse (start = "
+
str
(
start
)
+
" ns, width = "
+
str
(
width
)
+
" ns, "
+
StrPolarity
(
polarity
)
+
") (press Enter)"
)
for
width
in
range
(
10
,
13
+
1
):
TestSinglePulse
(
pg
,
channel
,
start
,
width
,
polarity
)
raw_input
(
"Shifting width of the pulse (start = "
+
str
(
start
)
+
" ns, width = "
+
str
(
width
)
+
" ns, "
+
StrPolarity
(
polarity
)
+
") (press Enter)"
)
# stop and disable channel
StopAndDisable
(
pg
,
channel
)
# print some info
pg
.
PrintVersion
()
print
(
"Actual temperature: "
+
str
(
pg
.
temp
.
ReadTemperature
())
+
" °C"
)
PrintFrequency
(
pg
)
pg
.
PrintControl
()
pg
.
PrintStatus
()
pg
.
PrintDebug
()
cont
=
raw_input
(
"Next test? (n - quit, Enter - next test): "
)
if
cont
==
"n"
:
break
sw/Ffpg.py
View file @
857483c0
...
...
@@ -31,6 +31,7 @@
## 2016-09-06 1.0 Jan Pospisil Derived from the initial example driver
## 2016-09-07 1.1 Jan Pospisil added AD9512 OUT4 fine delay
## 2016-09-21 1.2 Jan Pospisil added GetFmcSlot and LED test methods
## 2017-09-14 1.2.1 Jan Pospisil reformatted, added comments
##-----------------------------------------------------------------------------
import
time
...
...
@@ -62,40 +63,15 @@ class Ffpg(object):
def
GetFmcSlot
(
self
):
return
self
.
fmcSlot
def
GetVersion
(
self
):
version
=
self
.
wb
.
Read
(
"version"
)
major
=
(
version
>>
22
)
&
((
2
**
10
)
-
1
)
minor
=
(
version
>>
12
)
&
((
2
**
10
)
-
1
)
revision
=
version
&
((
2
**
12
)
-
1
)
return
[
major
,
minor
,
revision
]
def
PrintVersion
(
self
):
[
major
,
minor
,
revision
]
=
self
.
GetVersion
()
print
(
"Gateware version: "
+
str
(
major
)
+
"."
+
str
(
minor
)
+
"."
+
str
(
revision
))
def
CompareVersion
(
self
,
major
,
minor
,
revision
):
"""
check actual version against provided version
returns:
0 - versions are same
1 - actual version is newer than argument provided
-1 - actual version is older than argument provided
"""
[
actualMajor
,
actualMinor
,
actualRevision
]
=
self
.
GetVersion
()
if
actualMajor
>
major
:
return
1
if
actualMajor
<
major
:
return
-
1
if
actualMinor
>
minor
:
return
1
if
actualMinor
<
minor
:
return
-
1
if
actualRevision
>
revision
:
return
1
if
actualRevision
<
revision
:
return
-
1
return
0
#######################
# Common Configuration
#######################
def
Reset
(
self
):
self
.
ClearMemory
(
0
,
"*"
)
self
.
wb
.
Write
(
"control"
,
0
)
def
SelectClock
(
self
,
clockType
,
frequency
):
"""
...
...
@@ -123,14 +99,14 @@ class Ffpg(object):
def
GetRatio
(
self
):
ratiom1
=
self
.
wb
.
Read
(
"clock_ratio_m1"
)
return
ratiom1
+
1
def
SetOverflow
(
self
,
overflow
):
self
.
wb
.
Write
(
"overflow"
,
overflow
)
def
Ad9512Sync
(
self
):
""" synchronize AD9512 dividers """
self
.
wb
.
SetBits
(
"control"
,
1
<<
9
)
def
Ad9512ActivateWbAccess
(
self
):
self
.
wb
.
SetBits
(
"control"
,
1
<<
11
)
...
...
@@ -155,134 +131,31 @@ class Ffpg(object):
code
&=
(
2
**
bits
)
-
1
self
.
wb
.
Write
(
"vcxo_voltage"
,
code
)
def
GetFrequency
(
self
):
# return frequency of RF clock in Hz, if stable, None otherwise
status
=
self
.
wb
.
Read
(
"status"
)
if
(
status
&
(
1
<<
8
)
==
0
):
return
None
else
:
return
self
.
wb
.
Read
(
"frequency"
)
def
ClearMemory
(
self
,
channel
,
memory
,
memoryPart
=
-
1
):
def
SetClockFineDelay
(
self
,
fineDelay
,
current
=
0
,
capacitors
=
0
):
"""
channel = 1 | 2 | 0 (for both)
memory = 'set' | 'res' | '*' (for both memories)
if memoryPart > -1: clear only first memoryPart words
enable and set AD9512 OUT4 output fine delay
fineDelay = <0, 31>
"""
if
channel
==
0
:
self
.
ClearMemory
(
1
,
memory
,
memoryPart
)
self
.
ClearMemory
(
2
,
memory
,
memoryPart
)
return
assert
(
memory
==
"set"
)
or
(
memory
==
"res"
)
or
(
memory
==
"*"
),
"Bad memory!"
if
memory
==
"*"
:
self
.
ClearMemory
(
channel
,
"set"
,
memoryPart
)
self
.
ClearMemory
(
channel
,
"res"
,
memoryPart
)
return
partToClear
=
2048
to
=
-
1
if
memoryPart
>
-
1
:
partToClear
=
memoryPart
to
=
memoryPart
self
.
wb
.
WriteMulti
(
self
.
_GetChannelRegName
(
channel
,
memory
+
"_mem"
),
(
0
,)
*
partToClear
,
to
=
to
)
# enable fine delay
self
.
wb
.
SetBits
(
"control"
,
(
1
<<
10
))
# set fine delay
fineDelayReg
=
fineDelay
&
0x1F
fineDelayReg
|=
(
current
&
0x7
)
<<
5
fineDelayReg
|=
(
capacitors
&
0x7
)
<<
8
self
.
wb
.
Write
(
"fine_delay"
,
fineDelayReg
)
def
Reset
(
self
):
self
.
ClearMemory
(
0
,
"*"
)
self
.
wb
.
Write
(
"control"
,
0
)
def
DisableClockFineDelay
(
self
):
self
.
wb
.
SetBits
(
"control"
,
(
1
<<
10
),
0
)
#######################
# Pulse Channel Configuration
#######################
def
_GetChannelRegName
(
self
,
channel
,
name
):
assert
(
channel
==
1
)
or
(
channel
==
2
),
"Bad channel
\"
"
+
str
(
channel
)
+
"
\"
, we have only 2 channels!"
return
"ch"
+
str
(
channel
)
+
"_"
+
name
def
GetClockPeriod
(
self
):
""" return clock period in [ns] of the RF clock coming to the FPGA """
return
1000.0
/
(
self
.
inputClockFrequency
/
self
.
GetRatio
())
def
SetFineDelay
(
self
,
channel
,
memory
,
delayValue
):
"""
channel = 1 | 2
memory = "set" | "res"
delayValue in [ns]
"""
# compensate for calibration
delayValue
+=
self
.
fineTriggerPhase
[
channel
]
# calculate delay binary value
binaryValue
=
int
(
round
(
delayValue
*
100
))
# step is 10 ps
assert
binaryValue
<
2
**
10
,
"Fine delay is larger than the IC can handle!"
# set delay
self
.
wb
.
Write
(
self
.
_GetChannelRegName
(
channel
,
"delay_"
+
memory
),
binaryValue
)
def
SetTriggerPhase
(
self
,
channel
,
phase
):
""" phase in [ns] - depends on setup, cable length... """
clockPeriod
=
self
.
GetClockPeriod
()
bitPhase
=
int
(
phase
/
clockPeriod
)
# advance output pulse
finePhase
=
phase
-
bitPhase
*
clockPeriod
# delay output pulse
if
finePhase
>
0
:
bitPhase
+=
1
finePhase
=
clockPeriod
-
finePhase
self
.
wb
.
Write
(
self
.
_GetChannelRegName
(
channel
,
"trig_latency"
),
bitPhase
)
self
.
fineTriggerPhase
[
channel
]
=
finePhase
self
.
SetFineDelay
(
channel
,
"set"
,
0
)
def
PrintStatus
(
self
):
print
(
"Status register:"
)
status
=
self
.
wb
.
Read
(
"status"
)
PrintBit
(
status
,
0
,
"Clock infrastructure configuration"
,
"busy"
,
"idle"
)
PrintBit
(
status
,
1
,
"VCXO DAC"
,
"busy"
,
"idle"
)
PrintBit
(
status
,
2
,
"Trigger threshold DAC"
,
"busy"
,
"idle"
)
PrintBit
(
status
,
3
,
"Delay configuration"
,
"busy"
,
"idle"
)
PrintBit
(
status
,
4
,
"Channel 1 output"
,
"enabled"
,
"disabled"
)
PrintBit
(
status
,
5
,
"Channel 2 output"
,
"enabled"
,
"disabled"
)
PrintBit
(
status
,
6
,
"Channel 1"
,
"running"
,
"stopped"
)
PrintBit
(
status
,
7
,
"Channel 2"
,
"running"
,
"stopped"
)
PrintBit
(
status
,
8
,
"Input clock stability"
,
"stable"
,
"not stable/present"
)
def
PrintControl
(
self
):
print
(
"Control register: "
)
control
=
self
.
wb
.
Read
(
"control"
)
PrintBits
(
control
,
0
,
1
,
"Clock selection"
,
(
"external clock"
,
"FPGA LOOP"
,
"on-board VCXO"
))
PrintBit
(
control
,
2
,
"Channel 1 output"
,
"enabled"
,
"disabled"
)
PrintBit
(
control
,
3
,
"Channel 2 output"
,
"enabled"
,
"disabled"
)
PrintBits
(
control
,
4
,
5
,
"Channel 1 mode"
,
(
"stopped"
,
"continuous"
,
"one-shot"
))
PrintBits
(
control
,
6
,
7
,
"Channel 2 mode"
,
(
"stopped"
,
"continuous"
,
"one-shot"
))
PrintBit
(
control
,
8
,
"LEDs"
,
"blinking"
,
"normal operation"
)
PrintBit
(
control
,
9
,
"AD9512 Synchronization"
,
"in progress"
,
"done"
)
def
PrintDebug
(
self
):
print
(
"Debug:"
)
debug
=
self
.
wb
.
Read
(
"debug"
)
PrintBits
(
debug
,
0
,
2
,
"CH1 FSM state"
,
(
"Stop"
,
"WaitForTrigger"
,
"Generating"
,
"Outputting"
))
PrintBits
(
debug
,
3
,
5
,
"CH2 FSM state"
,
(
"Stop"
,
"WaitForTrigger"
,
"Generating"
,
"Outputting"
))
def
EnableChannel
(
self
,
channel
):
channel
-=
1
channel
%=
2
self
.
wb
.
SetBits
(
"control"
,
0x4
<<
channel
,
0x4
<<
channel
)
# set output enable
def
DisableChannel
(
self
,
channel
):
channel
-=
1
channel
%=
2
self
.
wb
.
SetBits
(
"control"
,
0x4
<<
channel
,
0
)
# set output disable
def
StartChannel
(
self
,
channel
):
channel
-=
1
channel
%=
2
channel
*=
2
self
.
wb
.
SetBits
(
"control"
,
0x30
<<
channel
,
0x10
<<
channel
)
# set mode CONT.
def
StartChannelOnce
(
self
,
channel
):
channel
-=
1
channel
%=
2
channel
*=
2
self
.
wb
.
SetBits
(
"control"
,
0x30
<<
channel
,
0x20
<<
channel
)
# set mode ONE-SHOT
def
StopChannel
(
self
,
channel
):
channel
-=
1
channel
%=
2
channel
*=
2
self
.
wb
.
SetBits
(
"control"
,
0x30
<<
channel
,
0
)
# set mode STOP
def
_ConfigurePulse
(
self
,
channel
,
setIndex
,
resIndex
,
pulse
,
which
=
0
):
"""
Manipulate the SET and RESET pulse generator arrays:
...
...
@@ -322,19 +195,55 @@ class Ffpg(object):
shift
=
resIndex
%
32
self
.
wb
.
SetBitsMulti
(
self
.
_GetChannelRegName
(
channel
,
"res_mem"
),
((
1
<<
shift
),),
((
pulse
<<
shift
),),
start
=
position
,
to
=
position
+
1
)
def
ResetBadState
(
self
,
channel
):
""" robust reset function to get out of the bad `state 1` """
self
.
DisableChannel
(
channel
)
#Outputs Hi-Z
self
.
StopChannel
(
channel
)
#Stop clock
self
.
ClearMemory
(
channel
,
"*"
)
#Clear the pulse generator arrays
# Define a single SET pulse per cycle,
# after two cycles, the MC100EP140 should be in the good
# state number 3 (output high)
self
.
_ConfigurePulse
(
channel
,
10
,
50
,
1
,
1
)
self
.
StartChannel
(
channel
)
#Enable clock
time
.
sleep
(
1e-3
)
self
.
StopChannel
(
channel
)
self
.
ClearMemory
(
channel
,
"*"
)
def
SetTriggerPhase
(
self
,
channel
,
phase
):
""" phase in [ns] - depends on setup, cable length... """
clockPeriod
=
self
.
GetClockPeriod
()
bitPhase
=
int
(
phase
/
clockPeriod
)
# advance output pulse
finePhase
=
phase
-
bitPhase
*
clockPeriod
# delay output pulse
if
finePhase
>
0
:
bitPhase
+=
1
finePhase
=
clockPeriod
-
finePhase
self
.
wb
.
Write
(
self
.
_GetChannelRegName
(
channel
,
"trig_latency"
),
bitPhase
)
self
.
fineTriggerPhase
[
channel
]
=
finePhase
self
.
SetFineDelay
(
channel
,
"set"
,
0
)
def
SetFineDelay
(
self
,
channel
,
memory
,
delayValue
):
"""
channel = 1 | 2
memory = "set" | "res"
delayValue in [ns]
"""
# compensate for calibration
delayValue
+=
self
.
fineTriggerPhase
[
channel
]
# calculate delay binary value
binaryValue
=
int
(
round
(
delayValue
*
100
))
# step is 10 ps
assert
binaryValue
<
2
**
10
,
"Fine delay is larger than the IC can handle!"
# set delay
self
.
wb
.
Write
(
self
.
_GetChannelRegName
(
channel
,
"delay_"
+
memory
),
binaryValue
)
def
ClearMemory
(
self
,
channel
,
memory
,
memoryPart
=
-
1
):
"""
channel = 1 | 2 | 0 (for both)
memory = 'set' | 'res' | '*' (for both memories)
if memoryPart > -1: clear only first memoryPart words
"""
if
channel
==
0
:
self
.
ClearMemory
(
1
,
memory
,
memoryPart
)
self
.
ClearMemory
(
2
,
memory
,
memoryPart
)
return
assert
(
memory
==
"set"
)
or
(
memory
==
"res"
)
or
(
memory
==
"*"
),
"Bad memory!"
if
memory
==
"*"
:
self
.
ClearMemory
(
channel
,
"set"
,
memoryPart
)
self
.
ClearMemory
(
channel
,
"res"
,
memoryPart
)
return
partToClear
=
2048
to
=
-
1
if
memoryPart
>
-
1
:
partToClear
=
memoryPart
to
=
memoryPart
self
.
wb
.
WriteMulti
(
self
.
_GetChannelRegName
(
channel
,
memory
+
"_mem"
),
(
0
,)
*
partToClear
,
to
=
to
)
def
CreateSinglePulse
(
self
,
channel
,
start
,
width
,
polarity
=
1
):
"""
...
...
@@ -362,7 +271,7 @@ class Ffpg(object):
self
.
SetFineDelay
(
channel
,
"res"
,
stopFineDelay
)
self
.
_ConfigurePulse
(
channel
,
startBit
,
stopBit
,
1
)
def
CreateBunchPulses
(
self
,
channel
,
pulseDelay
,
pulseWidth
,
bunches
,
polarity
=
1
):
"""
create set of pulses inside LHC bunches
...
...
@@ -424,21 +333,130 @@ class Ffpg(object):
else
:
self
.
_ConfigurePulse
(
channel
,
0
,
0
,
1
,
1
)
# only one set bit
def
SetClockFineDelay
(
self
,
fineDelay
,
current
=
0
,
capacitors
=
0
):
def
ResetBadState
(
self
,
channel
):
""" robust reset function to get out of the bad `state 1` """
self
.
DisableChannel
(
channel
)
#Outputs Hi-Z
self
.
StopChannel
(
channel
)
#Stop clock
self
.
ClearMemory
(
channel
,
"*"
)
#Clear the pulse generator arrays
# Define a single SET pulse per cycle,
# after two cycles, the MC100EP140 should be in the good
# state number 3 (output high)
self
.
_ConfigurePulse
(
channel
,
10
,
50
,
1
,
1
)
self
.
StartChannel
(
channel
)
#Enable clock
time
.
sleep
(
1e-3
)
self
.
StopChannel
(
channel
)
self
.
ClearMemory
(
channel
,
"*"
)
def
EnableChannel
(
self
,
channel
):
channel
-=
1
channel
%=
2
self
.
wb
.
SetBits
(
"control"
,
0x4
<<
channel
,
0x4
<<
channel
)
# set output enable
def
DisableChannel
(
self
,
channel
):
channel
-=
1
channel
%=
2
self
.
wb
.
SetBits
(
"control"
,
0x4
<<
channel
,
0
)
# set output disable
def
StartChannel
(
self
,
channel
):
channel
-=
1
channel
%=
2
channel
*=
2
self
.
wb
.
SetBits
(
"control"
,
0x30
<<
channel
,
0x10
<<
channel
)
# set mode CONT.
def
StartChannelOnce
(
self
,
channel
):
channel
-=
1
channel
%=
2
channel
*=
2
self
.
wb
.
SetBits
(
"control"
,
0x30
<<
channel
,
0x20
<<
channel
)
# set mode ONE-SHOT
def
StopChannel
(
self
,
channel
):
channel
-=
1
channel
%=
2
channel
*=
2
self
.
wb
.
SetBits
(
"control"
,
0x30
<<
channel
,
0
)
# set mode STOP
#######################
# Reporting, Debugging
#######################
def
GetVersion
(
self
):
version
=
self
.
wb
.
Read
(
"version"
)
major
=
(
version
>>
22
)
&
((
2
**
10
)
-
1
)
minor
=
(
version
>>
12
)
&
((
2
**
10
)
-
1
)
revision
=
version
&
((
2
**
12
)
-
1
)
return
[
major
,
minor
,
revision
]
def
PrintVersion
(
self
):
[
major
,
minor
,
revision
]
=
self
.
GetVersion
()
print
(
"Gateware version: "
+
str
(
major
)
+
"."
+
str
(
minor
)
+
"."
+
str
(
revision
))
def
CompareVersion
(
self
,
major
,
minor
,
revision
):
"""
enable and set AD9512 OUT4 output fine delay
fineDelay = <0, 31>
check actual version against provided version
returns:
0 - versions are same
1 - actual version is newer than argument provided
-1 - actual version is older than argument provided
"""
# enable fine delay
self
.
wb
.
SetBits
(
"control"
,
(
1
<<
10
))
# set fine delay
fineDelayReg
=
fineDelay
&
0x1F
fineDelayReg
|=
(
current
&
0x7
)
<<
5
fineDelayReg
|=
(
capacitors
&
0x7
)
<<
8
self
.
wb
.
Write
(
"fine_delay"
,
fineDelayReg
)
def
DisableClockFineDelay
(
self
):
self
.
wb
.
SetBits
(
"control"
,
(
1
<<
10
),
0
)
[
actualMajor
,
actualMinor
,
actualRevision
]
=
self
.
GetVersion
()
if
actualMajor
>
major
:
return
1
if
actualMajor
<
major
:
return
-
1
if
actualMinor
>
minor
:
return
1
if
actualMinor
<
minor
:
return
-
1
if
actualRevision
>
revision
:
return
1
if
actualRevision
<
revision
:
return
-
1
return
0
def
GetFrequency
(
self
):
# return frequency of RF clock in Hz, if stable, None otherwise
status
=
self
.
wb
.
Read
(
"status"
)
if
(
status
&
(
1
<<
8
)
==
0
):
return
None
else
:
return
self
.
wb
.
Read
(
"frequency"
)
def
GetClockPeriod
(
self
):
""" return clock period in [ns] of the RF clock coming to the FPGA """
return
1000.0
/
(
self
.
inputClockFrequency
/
self
.
GetRatio
())
def
PrintStatus
(
self
):
print
(
"Status register:"
)
status
=
self
.
wb
.
Read
(
"status"
)
PrintBit
(
status
,
0
,
"Clock infrastructure configuration"
,
"busy"
,
"idle"
)
PrintBit
(
status
,
1
,
"VCXO DAC"
,
"busy"
,
"idle"
)
PrintBit
(
status
,
2
,
"Trigger threshold DAC"
,
"busy"
,
"idle"
)
PrintBit
(
status
,
3
,
"Delay configuration"
,
"busy"
,
"idle"
)
PrintBit
(
status
,
4
,
"Channel 1 output"
,
"enabled"
,
"disabled"
)
PrintBit
(
status
,
5
,
"Channel 2 output"
,
"enabled"
,
"disabled"
)
PrintBit
(
status
,
6
,
"Channel 1"
,
"running"
,
"stopped"
)
PrintBit
(
status
,
7
,
"Channel 2"
,
"running"
,
"stopped"
)
PrintBit
(
status
,
8
,
"Input clock stability"
,
"stable"
,
"not stable/present"
)
def
PrintControl
(
self
):
print
(
"Control register: "
)
control
=
self
.
wb
.
Read
(
"control"
)
PrintBits
(
control
,
0
,
1
,
"Clock selection"
,
(
"external clock"
,
"FPGA LOOP"
,
"on-board VCXO"
))
PrintBit
(
control
,
2
,
"Channel 1 output"
,
"enabled"
,
"disabled"
)
PrintBit
(
control
,
3
,
"Channel 2 output"
,
"enabled"
,
"disabled"
)
PrintBits
(
control
,
4
,
5
,
"Channel 1 mode"
,
(
"stopped"
,
"continuous"
,
"one-shot"
))
PrintBits
(
control
,
6
,
7
,
"Channel 2 mode"
,
(
"stopped"
,
"continuous"
,
"one-shot"
))
PrintBit
(
control
,
8
,
"LEDs"
,
"blinking"
,
"normal operation"
)
PrintBit
(
control
,
9
,
"AD9512 Synchronization"
,
"in progress"
,
"done"
)
PrintBit
(
control
,
10
,
"AD9512 Fine Delay"
,
"enabled"
,
"disabled"
)
PrintBit
(
control
,
11
,
"AD9512 SPI mode"
,
"WB bridge"
,
"automatic mode"
)
def
PrintDebug
(
self
):
print
(
"Debug:"
)
debug
=
self
.
wb
.
Read
(
"debug"
)
PrintBits
(
debug
,
0
,
2
,
"CH1 FSM state"
,
(
"Stop"
,
"WaitForTrigger"
,
"Generating"
,
"Outputting"
))
PrintBits
(
debug
,
3
,
5
,
"CH2 FSM state"
,
(
"Stop"
,
"WaitForTrigger"
,
"Generating"
,
"Outputting"
))
def
LedModeTest
(
self
):
self
.
wb
.
SetBits
(
"control"
,
(
1
<<
8
))
...
...
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