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
f1d55d46
Commit
f1d55d46
authored
Sep 06, 2011
by
Matthieu Cattin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add fmcadc100m14b4cha test dir and script
parent
4a78fffb
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
36 changed files
with
3815 additions
and
0 deletions
+3815
-0
fmcadc100m14b4cha.sh
fmcadc100m14b4cha.sh
+40
-0
spec_fmcadc100m14b4cha.bin
test/fmcadc100m14b4cha/firmwares/spec_fmcadc100m14b4cha.bin
+0
-0
ADC.py
test/fmcadc100m14b4cha/python/PAGE/ADC.py
+44
-0
Agilent33250A.py
test/fmcadc100m14b4cha/python/PAGE/Agilent33250A.py
+362
-0
Generator.py
test/fmcadc100m14b4cha/python/PAGE/Generator.py
+29
-0
Item.py
test/fmcadc100m14b4cha/python/PAGE/Item.py
+26
-0
RemoteObject.py
test/fmcadc100m14b4cha/python/PAGE/RemoteObject.py
+20
-0
SineWaveform.py
test/fmcadc100m14b4cha/python/PAGE/SineWaveform.py
+58
-0
Sis33.py
test/fmcadc100m14b4cha/python/PAGE/Sis33.py
+491
-0
TTWaveform.py
test/fmcadc100m14b4cha/python/PAGE/TTWaveform.py
+61
-0
Utilities.py
test/fmcadc100m14b4cha/python/PAGE/Utilities.py
+29
-0
Waveform.py
test/fmcadc100m14b4cha/python/PAGE/Waveform.py
+24
-0
__init__.py
test/fmcadc100m14b4cha/python/PAGE/__init__.py
+26
-0
csr.py
test/fmcadc100m14b4cha/python/csr.py
+36
-0
ds18b20.py
test/fmcadc100m14b4cha/python/ds18b20.py
+91
-0
fmc_adc.py
test/fmcadc100m14b4cha/python/fmc_adc.py
+454
-0
gn4124.py
test/fmcadc100m14b4cha/python/gn4124.py
+198
-0
i2c.py
test/fmcadc100m14b4cha/python/i2c.py
+111
-0
ltc217x.py
test/fmcadc100m14b4cha/python/ltc217x.py
+95
-0
max5442.py
test/fmcadc100m14b4cha/python/max5442.py
+23
-0
onewire.py
test/fmcadc100m14b4cha/python/onewire.py
+110
-0
ptsexcept.py
test/fmcadc100m14b4cha/python/ptsexcept.py
+35
-0
rr.py
test/fmcadc100m14b4cha/python/rr.py
+205
-0
rrlib.so
test/fmcadc100m14b4cha/python/rrlib.so
+0
-0
si57x.py
test/fmcadc100m14b4cha/python/si57x.py
+114
-0
spi.py
test/fmcadc100m14b4cha/python/spi.py
+83
-0
test00.py
test/fmcadc100m14b4cha/python/test00.py
+83
-0
test01.py
test/fmcadc100m14b4cha/python/test01.py
+81
-0
test02.py
test/fmcadc100m14b4cha/python/test02.py
+49
-0
test03.py
test/fmcadc100m14b4cha/python/test03.py
+67
-0
test04.py
test/fmcadc100m14b4cha/python/test04.py
+66
-0
test05.py
test/fmcadc100m14b4cha/python/test05.py
+64
-0
test06.py
test/fmcadc100m14b4cha/python/test06.py
+93
-0
test07.py
test/fmcadc100m14b4cha/python/test07.py
+98
-0
test08.py
test/fmcadc100m14b4cha/python/test08.py
+258
-0
test09.py
test/fmcadc100m14b4cha/python/test09.py
+191
-0
No files found.
fmcadc100m14b4cha.sh
0 → 100755
View file @
f1d55d46
#!/bin/sh
# Copyright CERN, 2011
# Author: Matthieu Cattin <matthieu.cattin@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
LOGDIR
=
./log_fmcadc100m14b4cha
mkdir
-p
$LOGDIR
sudo rm
-fr
$LOGDIR
/pts
*
serial
=
$1
if
[
x
$1
=
x
""
]
;
then
echo
-n
"Please, input SERIAL number: "
read
serial
fi
if
[
x
$serial
=
x
""
]
;
then
serial
=
0000
fi
extra_serial
=
$2
if
[
x
$2
=
x
""
]
;
then
echo
-n
"Please, input extra SERIAL number: "
read
extra_serial
fi
if
[
x
$extra_serial
=
x
""
]
;
then
extra_serial
=
0000
fi
echo
-n
"--------------------------------------------------------------
\n
"
sudo
./pts.py
-b
FmcAdc100M14b4cha
-s
$serial
-e
$extra_serial
-t
./test/fmcadc100m14b4cha/python
-l
$LOGDIR
00 01 02 03 04 05 06 07 08
echo
-n
"Press enter to exit... "
read
tmp
test/fmcadc100m14b4cha/firmwares/spec_fmcadc100m14b4cha.bin
0 → 100644
View file @
f1d55d46
File added
test/fmcadc100m14b4cha/python/PAGE/ADC.py
0 → 100644
View file @
f1d55d46
from
Utilities
import
*
from
Item
import
*
"""This class manages a generic waveform generator."""
class
ADC
(
Item
):
def
get
(
self
,
what
):
"""Get an attribute value. Supports Pyro4."""
return
self
.
__getattribute__
(
what
)
def
set
(
self
,
what
,
how
):
"""Set an attribute value. Supports Pyro4."""
self
.
__setattr__
(
what
,
how
)
def
clockFrequency
():
doc
=
"Clock frequency used by the ADC"
def
fget
(
self
):
return
0
def
fset
(
self
,
value
):
return
return
locals
()
@
Property
def
clockFrequencies
():
doc
=
"Clock frequencies"
def
fget
(
self
):
return
tuple
()
def
fset
(
self
,
value
):
return
return
locals
()
@
Property
def
nrBits
():
doc
=
"Number of bits of the device."
def
fget
(
self
):
return
0
return
locals
()
def
readEvent
(
self
,
samples
):
'''Read an event of size 'samples' from the ADC. Uses self.segment
and self.channel to select the missing parameters.'''
return
[]
def
__init__
(
self
,
*
args
,
**
kwargs
):
Item
.
__init__
(
self
,
*
args
,
**
kwargs
)
test/fmcadc100m14b4cha/python/PAGE/Agilent33250A.py
0 → 100644
View file @
f1d55d46
This diff is collapsed.
Click to expand it.
test/fmcadc100m14b4cha/python/PAGE/Generator.py
0 → 100644
View file @
f1d55d46
from
Utilities
import
*
from
Item
import
*
"""This class manages a generic waveform generator."""
class
Generator
(
Item
):
def
get
(
self
,
what
):
"""Get an attribute value. Supports Pyro4."""
return
self
.
__getattribute__
(
what
)
def
set
(
self
,
what
,
how
):
"""Set an attribute value. Supports Pyro4."""
self
.
__setattr__
(
what
,
how
)
# this dictionary is used to map data types into function which can
# translate such type of data into something the generator can understand.
adaptDict
=
{}
def
adaptKeys
(
self
):
"""Returns all data types supported."""
return
self
.
adaptDict
.
keys
()
def
adapt
(
self
,
wave
,
*
args
,
**
kwargs
):
"""Adapt a wave to the generator"""
return
self
.
adaptDict
[
type
(
wave
)](
wave
,
*
args
,
**
kwargs
)
def
__init__
(
self
,
*
args
,
**
kwargs
):
Item
.
__init__
(
self
,
*
args
,
**
kwargs
)
test/fmcadc100m14b4cha/python/PAGE/Item.py
0 → 100644
View file @
f1d55d46
"""This class just represent an API item. An item is configurable and has two
methods, get and set, which actually wrap getattribute and setattr."""
class
Item
(
object
):
# these are the default values of the parameters used
#
# the key of the dictionary is the actual name of the parameter in the class
# the item is a list:
# 1. Name of the parameter
# 2. Description
# 3. Default value
# 4. Type (it's just an object, really)
_parameters
=
{}
def
__init__
(
self
,
*
args
,
**
kwargs
):
"""Create the object and loads alll the parameters from kwargs.
Look at _parameters for more information."""
self
.
parameters
=
dict
(
self
.
_parameters
)
for
i
in
kwargs
:
if
i
in
self
.
parameters
.
keys
():
self
.
parameters
[
i
][
2
]
=
kwargs
[
i
]
for
i
in
self
.
parameters
.
keys
():
self
.
__setattr__
(
i
,
self
.
parameters
[
i
][
2
])
test/fmcadc100m14b4cha/python/PAGE/RemoteObject.py
0 → 100644
View file @
f1d55d46
import
sys
import
Pyro4
import
Item
from
Utilities
import
*
from
numpy
import
*
"""This class represents a remote object, using Pyro4 framework.
All it needs is a URI."""
class
RemoteObject
(
Item
.
Item
,
Pyro4
.
Proxy
):
_parameters
=
{
'uri'
:
[
'URI'
,
'Name of the service'
,
''
,
str
]}
def
__init__
(
self
,
*
args
,
**
kwargs
):
Item
.
Item
.
__init__
(
self
,
*
args
,
**
kwargs
)
Pyro4
.
Proxy
.
__init__
(
self
,
uri
=
Pyro4
.
locateNS
()
.
lookup
(
self
.
uri
))
name
=
'Remote Object'
target
=
RemoteObject
test/fmcadc100m14b4cha/python/PAGE/SineWaveform.py
0 → 100644
View file @
f1d55d46
import
Waveform
from
Utilities
import
*
from
numpy
import
*
import
Pyro4
import
Pyro4.util
import
sys
class
SineWaveform
(
Waveform
.
Waveform
):
def
get
(
self
,
what
):
return
self
.
__getattribute__
(
what
)
def
set
(
self
,
what
,
how
):
self
.
__setattr__
(
what
,
how
)
_parameters
=
{
'frequency'
:[
'Frequency'
,
'Frequency of the sinewave, in HZ'
,
1000
,
float
],
'amplitude'
:[
'Amplitude'
,
'Amplitude of the sinewave, in Vpp'
,
1
,
float
],
'dc'
:[
'DC Compoment'
,
'DC component of the sinewave, in Vpp'
,
0
,
float
]}
def
__init__
(
self
,
*
args
,
**
kwargs
):
Waveform
.
Waveform
.
__init__
(
self
,
*
args
,
**
kwargs
)
def
generate
(
self
,
sampleRate
,
samples
,
nbits
,
fsr
):
f
=
self
.
frequency
A
=
self
.
amplitude
C
=
self
.
dc
t
=
arange
(
samples
,
dtype
=
float
)
/
sampleRate
s
=
A
*
sin
(
2
*
pi
*
f
*
t
)
+
C
lsb
=
fsr
/
(
2
**
nbits
)
return
(
s
/
lsb
)
.
astype
(
int
)
def
scale
(
self
,
factor
):
"""Multiply the frequency by factor."""
self
.
frequency
*=
factor
return
self
name
=
'Sine Waveform'
target
=
SineWaveform
import
commands
def
launch
():
g
=
target
()
hn
=
commands
.
getoutput
(
'hostname'
)
daemon
=
Pyro4
.
Daemon
(
host
=
hn
)
myUri
=
daemon
.
register
(
g
)
ns
=
Pyro4
.
locateNS
()
ns
.
register
(
"Sine"
,
myUri
)
daemon
.
requestLoop
()
if
__name__
==
'__main__'
:
launch
()
test/fmcadc100m14b4cha/python/PAGE/Sis33.py
0 → 100644
View file @
f1d55d46
This diff is collapsed.
Click to expand it.
test/fmcadc100m14b4cha/python/PAGE/TTWaveform.py
0 → 100644
View file @
f1d55d46
import
Waveform
from
Utilities
import
*
from
numpy
import
*
import
Pyro4
import
Pyro4.util
import
sys
import
commands
class
TTWaveform
(
Waveform
.
Waveform
):
def
get
(
self
,
what
):
return
self
.
__getattribute__
(
what
)
def
set
(
self
,
what
,
how
):
self
.
__setattr__
(
what
,
how
)
_parameters
=
{
'frequency'
:[
'Frequency (1)'
,
'Frequency of the first sinewave, in HZ'
,
float
(
5e6
),
float
],
'ratio'
:[
'Ratio'
,
'Ratio between the frequency of the second sinewave and the one'
,
6.
/
5.
,
float
],
'amplitude'
:[
'Amplitude'
,
'Amplitude of each sinewave, in Vpp'
,
1.
,
float
],
'dc'
:[
'DC Compoment'
,
'DC component of the whole waveform, in Vpp'
,
0.
,
float
]}
def
__init__
(
self
,
*
args
,
**
kwargs
):
Waveform
.
Waveform
.
__init__
(
self
,
*
args
,
**
kwargs
)
def
generate
(
self
,
sampleRate
,
samples
,
nbits
,
fsr
):
f1
,
f2
=
self
.
frequency
,
self
.
frequency
*
self
.
ratio
A
=
self
.
amplitude
C
=
self
.
dc
t
=
arange
(
samples
,
dtype
=
float
)
/
sampleRate
s
=
A
*
sin
(
2
*
pi
*
f1
*
t
)
+
A
*
sin
(
2
*
pi
*
f2
*
t
)
+
C
lsb
=
fsr
/
(
2
**
nbits
)
return
(
s
/
lsb
)
.
astype
(
int
)
def
scale
(
self
,
factor
):
"""Multiply the frequency by factor"""
self
.
frequency
*=
factor
return
self
name
=
'Two Tones Waveform'
target
=
TTWaveform
def
launch
():
g
=
target
()
hn
=
commands
.
getoutput
(
'hostname'
)
daemon
=
Pyro4
.
Daemon
(
host
=
hn
)
myUri
=
daemon
.
register
(
g
)
ns
=
Pyro4
.
locateNS
()
ns
.
register
(
"TTSine"
,
myUri
)
daemon
.
requestLoop
()
if
__name__
==
'__main__'
:
launch
()
test/fmcadc100m14b4cha/python/PAGE/Utilities.py
0 → 100644
View file @
f1d55d46
def
Property
(
func
):
return
property
(
**
func
())
decodeDict
=
{
'KHZ'
:
3
,
'MHZ'
:
6
,
'HZ'
:
0
,
'UHZ'
:
-
6
,
'NHZ'
:
9
,
'MV'
:
-
3
,
'NV'
:
-
6
,
'KV'
:
3
,
'V'
:
0
,
'MVPP'
:
-
3
,
'NVPP'
:
-
6
,
'KVPP'
:
3
,
'VPP'
:
0
}
def
decode
(
values
):
return
float
(
values
[
0
])
*
(
10.
**
float
(
decodeDict
[
values
[
1
]
.
upper
()]))
def
parse
(
value
,
s
):
if
type
(
value
)
is
str
:
value
=
value
.
split
(
" "
)
value
[
0
]
=
float
(
value
[
0
])
value
=
tuple
(
value
)
if
type
(
value
)
is
tuple
and
len
(
value
)
==
1
:
value
=
value
[
0
]
if
type
(
value
)
is
not
tuple
:
value
=
(
value
,
s
)
return
tuple
(
str
(
i
)
for
i
in
value
)
def
prettyParameter
(
x
,
vx
):
print
'Parameter
%
s is called
%
s.'
%
(
x
,
vx
[
0
])
print
'Description:'
,
vx
[
1
]
print
'Default value, in
%
s, is
%
s'
%
(
repr
(
vx
[
3
]),
repr
(
vx
[
2
]))
test/fmcadc100m14b4cha/python/PAGE/Waveform.py
0 → 100644
View file @
f1d55d46
from
numpy
import
array
from
Item
import
*
"""This class represent a generic waveform."""
class
Waveform
(
Item
):
def
get
(
self
,
what
):
"""Get an attribute value. Supports Pyro4."""
return
self
.
__getattribute__
(
what
)
def
set
(
self
,
what
,
how
):
"""Set an attribute value. Supports Pyro4."""
self
.
__setattr__
(
what
,
how
)
"""A waveform must provide this method.
Create a numeric array which represents the wave."""
def
generate
(
self
,
nbits
,
frequency
,
samples
,
fsr
):
return
array
([])
def
__init__
(
self
,
*
args
,
**
kwargs
):
Item
.
__init__
(
self
,
*
args
,
**
kwargs
)
def
getType
(
self
):
return
type
(
self
)
test/fmcadc100m14b4cha/python/PAGE/__init__.py
0 → 100644
View file @
f1d55d46
__author__
=
"Federico"
__date__
=
"$Aug 17, 2011 4:43:08 PM$"
# PAGE: Python ADC and GEnerators API
hasSis33
=
False
import
SineWaveform
,
TTWaveform
import
Agilent33250A
import
RemoteObject
try
:
import
Sis33
hasSis33
=
True
except
:
print
'Error while loading Sis33 module, skipping it'
waveforms
=
(
RemoteObject
,
SineWaveform
,
TTWaveform
)
generators
=
(
Agilent33250A
,
RemoteObject
)
if
hasSis33
:
adcs
=
(
RemoteObject
,
Sis33
)
else
:
adcs
=
(
RemoteObject
,
)
test/fmcadc100m14b4cha/python/csr.py
0 → 100644
View file @
f1d55d46
#!/usr/bin/python
import
sys
import
rr
import
time
class
CCSR
:
def
__init__
(
self
,
bus
,
base_addr
):
self
.
base_addr
=
base_addr
;
self
.
bus
=
bus
;
def
wr_reg
(
self
,
addr
,
val
):
#print(" wr:%.8X reg:%.8X")%(val,(self.base_addr+addr))
self
.
bus
.
iwrite
(
0
,
self
.
base_addr
+
addr
,
4
,
val
)
def
rd_reg
(
self
,
addr
):
reg
=
self
.
bus
.
iread
(
0
,
self
.
base_addr
+
addr
,
4
)
#print(" reg:%.8X value:%.8X")%((self.base_addr+addr), reg)
return
reg
def
wr_bit
(
self
,
addr
,
bit
,
value
):
reg
=
self
.
rd_reg
(
addr
)
if
(
0
==
value
):
reg
&=
~
(
1
<<
bit
)
else
:
reg
|=
(
1
<<
bit
)
self
.
wr_reg
(
addr
,
reg
)
def
rd_bit
(
self
,
addr
,
bit
):
if
(
self
.
rd_reg
(
addr
)
&
(
1
<<
bit
)):
return
1
else
:
return
0
test/fmcadc100m14b4cha/python/ds18b20.py
0 → 100644
View file @
f1d55d46
#!/usr/bin/python
import
sys
import
rr
import
time
import
onewire
class
CDS18B20
:
# ROM commands
ROM_SEARCH
=
0xF0
ROM_READ
=
0x33
ROM_MATCH
=
0x55
ROM_SKIP
=
0xCC
ROM_ALARM_SEARCH
=
0xEC
# DS18B20 fonctions commands
CONVERT_TEMP
=
0x44
WRITE_SCRATCHPAD
=
0x4E
READ_SCRATCHPAD
=
0xBE
COPY_SCRATCHPAD
=
0x48
RECALL_EEPROM
=
0xB8
READ_POWER_SUPPLY
=
0xB4
# Thermometer resolution configuration
RES
=
{
'9-bit'
:
0x0
,
'10-bit'
:
0x1
,
'11-bit'
:
0x2
,
'12-bit'
:
0x3
}
def
__init__
(
self
,
onewire
,
port
):
self
.
onewire
=
onewire
self
.
port
=
port
def
read_serial_number
(
self
):
#print('[DS18B20] Reading serial number')
if
(
1
!=
self
.
onewire
.
reset
(
self
.
port
)):
print
(
'[DS18B20] No presence pulse detected'
)
return
-
1
else
:
#print('[DS18B20] Write ROM command %.2X') % self.ROM_READ
err
=
self
.
onewire
.
write_byte
(
self
.
port
,
self
.
ROM_READ
)
if
(
err
!=
0
):
print
(
'[DS18B20] Write error'
)
return
-
1
family_code
=
self
.
onewire
.
read_byte
(
self
.
port
)
serial_number
=
0
for
i
in
range
(
6
):
serial_number
|=
self
.
onewire
.
read_byte
(
self
.
port
)
<<
(
i
*
8
)
crc
=
self
.
onewire
.
read_byte
(
self
.
port
)
#print('[DS18B20] Family code : %.2X') % family_code
#print('[DS18B20] Serial number: %.12X') % serial_number
#print('[DS18B20] CRC : %.2X') % crc
return
((
crc
<<
56
)
|
(
serial_number
<<
8
)
|
family_code
)
def
access
(
self
,
serial_number
):
#print('[DS18B20] Accessing device')
if
(
1
!=
self
.
onewire
.
reset
(
self
.
port
)):
print
(
'[DS18B20] No presence pulse detected'
)
return
-
1
else
:
#print('[DS18B20] Write ROM command %.2X') % self.ROM_MATCH
err
=
self
.
onewire
.
write_byte
(
self
.
port
,
self
.
ROM_MATCH
)
#print serial_number
block
=
[]
for
i
in
range
(
8
):
block
.
append
(
serial_number
&
0xFF
)
serial_number
>>=
8
#print block
self
.
onewire
.
write_block
(
self
.
port
,
block
)
return
0
def
read_temp
(
self
,
serial_number
):
#print('[DS18B20] Reading temperature')
err
=
self
.
access
(
serial_number
)
#print('[DS18B20] Write function command %.2X') % self.CONVERT_TEMP
err
=
self
.
onewire
.
write_byte
(
self
.
port
,
self
.
CONVERT_TEMP
)
time
.
sleep
(
1
)
err
=
self
.
access
(
serial_number
)
#print('[DS18B20] Write function command %.2X') % self.READ_SCRATCHPAD
err
=
self
.
onewire
.
write_byte
(
self
.
port
,
self
.
READ_SCRATCHPAD
)
data
=
self
.
onewire
.
read_block
(
self
.
port
,
9
)
#for i in range(9):
# print('Scratchpad data[%1d]: %.2X') % (i, data[i])
temp
=
(
data
[
1
]
<<
8
)
|
(
data
[
0
])
if
(
temp
&
0x1000
):
temp
=
-
0x10000
+
temp
temp
=
temp
/
16.0
return
temp
# Set temperature thresholds
# Configure thermometer resolution
test/fmcadc100m14b4cha/python/fmc_adc.py
0 → 100644
View file @
f1d55d46
This diff is collapsed.
Click to expand it.
test/fmcadc100m14b4cha/python/gn4124.py
0 → 100644
View file @
f1d55d46
#!/usr/bin/python
import
sys
import
rr
import
time
import
csr
class
CGN4124
:
# Host registers (BAR12), for DMA items storage
HOST_BAR
=
0xC
HOST_DMA_CARRIER_START_ADDR
=
0x00
HOST_DMA_HOST_START_ADDR_L
=
0x04
HOST_DMA_HOST_START_ADDR_H
=
0x08
HOST_DMA_LENGTH
=
0x0C
HOST_DMA_NEXT_ITEM_ADDR_L
=
0x10
HOST_DMA_NEXT_ITEM_ADDR_H
=
0x14
HOST_DMA_ATTRIB
=
0x18
# GN4124 chip registers (BAR4)
GN4124_BAR
=
0x4
R_CLK_CSR
=
0x808
R_INT_CFG0
=
0x820
R_GPIO_DIR_MODE
=
0xA04
R_GPIO_INT_MASK_CLR
=
0xA18
R_GPIO_INT_MASK_SET
=
0xA1C
R_GPIO_INT_STATUS
=
0xA20
R_GPIO_INT_VALUE
=
0xA28
CLK_CSR_DIVOT_MASK
=
0x3F0
INT_CFG0_GPIO
=
15
GPIO_INT_SRC
=
8
# GN4124 core registers (BAR0)
R_DMA_CTL
=
0x00
R_DMA_STA
=
0x04
R_DMA_CARRIER_START_ADDR
=
0x08
R_DMA_HOST_START_ADDR_L
=
0x0C
R_DMA_HOST_START_ADDR_H
=
0x10
R_DMA_LENGTH
=
0x14
R_DMA_NEXT_ITEM_ADDR_L
=
0x18
R_DMA_NEXT_ITEM_ADDR_H
=
0x1C
R_DMA_ATTRIB
=
0x20
DMA_CTL_START
=
0
DMA_CTL_ABORT
=
1
DMA_CTL_SWAP
=
2
DMA_STA
=
[
'Idle'
,
'Done'
,
'Busy'
,
'Error'
,
'Aborted'
]
DMA_ATTRIB_LAST
=
0
DMA_ATTRIB_DIR
=
1
def
rd_reg
(
self
,
bar
,
addr
):
return
self
.
bus
.
iread
(
bar
,
addr
,
4
)
def
wr_reg
(
self
,
bar
,
addr
,
value
):
self
.
bus
.
iwrite
(
bar
,
addr
,
4
,
value
)
def
__init__
(
self
,
bus
,
csr_addr
):
self
.
bus
=
bus
self
.
dma_csr
=
csr
.
CCSR
(
bus
,
csr_addr
)
self
.
dma_item_cnt
=
0
# Get page list
self
.
pages
=
self
.
bus
.
getplist
()
# Shift by 12 to get the 32-bit physical addresses
self
.
pages
=
[
addr
<<
12
for
addr
in
self
.
pages
]
self
.
set_interrupt_config
()
# Enable interrupt from gn4124
self
.
bus
.
irqena
()
# Set local bus frequency
def
set_local_bus_freq
(
self
,
freq
):
# freq in MHz
# LCLK = (25MHz*(DIVFB+1))/(DIVOT+1)
# DIVFB = 31
# DIVOT = (800/LCLK)-1
divot
=
int
(
round
((
800
/
freq
)
-
1
,
0
))
#print '%d' % divot
data
=
0xe001f00c
+
(
divot
<<
4
)
#print '%.8X' % data
#print 'Set local bus freq to %dMHz' % int(round(800/(divot+1),0))
self
.
wr_reg
(
self
.
GN4124_BAR
,
self
.
R_CLK_CSR
,
data
)
# Get local bus frequency
# return: frequency in MHz
def
get_local_bus_freq
(
self
):
reg
=
self
.
rd_reg
(
self
.
GN4124_BAR
,
self
.
R_CLK_CSR
)
divot
=
((
reg
&
self
.
CLK_CSR_DIVOT_MASK
)
>>
4
)
return
(
800
/
(
divot
+
1
))
# Get physical addresses of the pages allocated to GN4124
def
get_physical_addr
(
self
):
return
self
.
pages
# Wait for interrupt
def
wait_irq
(
self
):
# Add here reading of the interrupt source (once the irq core will be present)
return
self
.
bus
.
irqwait
()
# GN4124 interrupt configuration
def
set_interrupt_config
(
self
):
# Set interrupt line from FPGA (GPIO8) as input
self
.
wr_reg
(
self
.
GN4124_BAR
,
self
.
R_GPIO_DIR_MODE
,
(
1
<<
self
.
GPIO_INT_SRC
))
# Set interrupt mask for all GPIO except for GPIO8
self
.
wr_reg
(
self
.
GN4124_BAR
,
self
.
R_GPIO_INT_MASK_SET
,
~
(
1
<<
self
.
GPIO_INT_SRC
))
# Make sure the interrupt mask is cleared for GPIO8
self
.
wr_reg
(
self
.
GN4124_BAR
,
self
.
R_GPIO_INT_MASK_CLR
,
(
1
<<
self
.
GPIO_INT_SRC
))
# Interrupt on rising edge of GPIO8
self
.
wr_reg
(
self
.
GN4124_BAR
,
self
.
R_GPIO_INT_VALUE
,
(
1
<<
self
.
GPIO_INT_SRC
))
# GPIO as interrupt 0 source
self
.
wr_reg
(
self
.
GN4124_BAR
,
self
.
R_INT_CFG0
,
(
1
<<
self
.
INT_CFG0_GPIO
))
# Get DMA controller status
def
get_dma_status
(
self
):
reg
=
self
.
dma_csr
.
rd_reg
(
self
.
R_DMA_STA
)
if
(
reg
>
len
(
self
.
DMA_STA
)):
print
(
"DMA status register :
%.8
X"
)
%
reg
raise
Exception
(
'Invalid DMA status'
)
else
:
return
self
.
DMA_STA
[
reg
]
# Configure DMA byte swapping
# 0 = A1 B2 C3 D4 (straight)
# 1 = B2 A1 D4 C3 (swap bytes in words)
# 2 = C3 D4 A1 B2 (swap words)
# 3 = D4 C3 B2 A1 (invert bytes)
def
set_dma_swap
(
self
,
swap
):
if
(
swap
>
3
):
raise
Exception
(
'Invalid swapping configuration :
%
d'
)
%
swap
else
:
self
.
dma_csr
.
wr_reg
(
self
.
R_CTL
,
(
swap
<<
self
.
DMA_CTL_SWAP
))
# Add DMA item (first item is on the board, the following in the host memory)
# carrier_addr, host_addr, length and next_item_addr are in bytes
# dma_dir = 1 -> PCIe to carrier
# dma_dir = 0 -> carrier to PCIe
# dma_last = 0 -> last item in the transfer
# dma_last = 1 -> more item in the transfer
# Only supports 32-bit host address
def
add_dma_item
(
self
,
carrier_addr
,
host_addr
,
length
,
dma_dir
,
last_item
):
if
(
0
==
self
.
dma_item_cnt
):
# write the first DMA item in the carrier
self
.
dma_csr
.
wr_reg
(
self
.
R_DMA_CARRIER_START_ADDR
,
carrier_addr
)
self
.
dma_csr
.
wr_reg
(
self
.
R_DMA_HOST_START_ADDR_L
,
(
host_addr
&
0xFFFFFFFF
))
self
.
dma_csr
.
wr_reg
(
self
.
R_DMA_HOST_START_ADDR_H
,
(
host_addr
>>
32
))
self
.
dma_csr
.
wr_reg
(
self
.
R_DMA_LENGTH
,
length
)
self
.
dma_csr
.
wr_reg
(
self
.
R_DMA_NEXT_ITEM_ADDR_L
,
(
self
.
pages
[
0
]
&
0xFFFFFFFF
))
self
.
dma_csr
.
wr_reg
(
self
.
R_DMA_NEXT_ITEM_ADDR_H
,
0x0
)
attrib
=
(
dma_dir
<<
self
.
DMA_ATTRIB_DIR
)
+
(
last_item
<<
self
.
DMA_ATTRIB_LAST
)
self
.
dma_csr
.
wr_reg
(
self
.
R_DMA_ATTRIB
,
attrib
)
else
:
# write nexy DMA item(s) in host memory
# uses page 0 to store DMA items
# current and next item addresses are automatically set
current_item_addr
=
(
self
.
dma_item_cnt
-
1
)
*
0x20
next_item_addr
=
(
self
.
dma_item_cnt
)
*
0x20
self
.
wr_reg
(
self
.
HOST_BAR
,
self
.
HOST_DMA_CARRIER_START_ADDR
+
current_item_addr
,
carrier_addr
)
self
.
wr_reg
(
self
.
HOST_BAR
,
self
.
HOST_DMA_HOST_START_ADDR_L
+
current_item_addr
,
host_addr
)
self
.
wr_reg
(
self
.
HOST_BAR
,
self
.
HOST_DMA_HOST_START_ADDR_H
+
current_item_addr
,
0x0
)
self
.
wr_reg
(
self
.
HOST_BAR
,
self
.
HOST_DMA_LENGTH
+
current_item_addr
,
length
)
self
.
wr_reg
(
self
.
HOST_BAR
,
self
.
HOST_DMA_NEXT_ITEM_ADDR_L
+
current_item_addr
,
self
.
pages
[
0
]
+
next_item_addr
)
self
.
wr_reg
(
self
.
HOST_BAR
,
self
.
HOST_DMA_NEXT_ITEM_ADDR_H
+
current_item_addr
,
0x0
)
attrib
=
(
dma_dir
<<
self
.
DMA_ATTRIB_DIR
)
+
(
last_item
<<
self
.
DMA_ATTRIB_LAST
)
self
.
wr_reg
(
self
.
HOST_BAR
,
self
.
HOST_DMA_ATTRIB
+
current_item_addr
,
attrib
)
self
.
dma_item_cnt
+=
1
# Start DMA transfer
def
start_dma
(
self
):
self
.
dma_item_cnt
=
0
self
.
dma_csr
.
wr_bit
(
self
.
R_DMA_CTL
,
self
.
DMA_CTL_START
,
1
)
# The following two lines should be removed
# when the GN4124 vhdl core will implement auto clear of start bit
#while(('Idle' == self.get_dma_status()) or
# ('Busy' == self.get_dma_status())):
# pass
self
.
dma_csr
.
wr_bit
(
self
.
R_DMA_CTL
,
self
.
DMA_CTL_START
,
0
)
# Abort DMA transfer
def
abort_dma
(
self
):
self
.
dma_item_cnt
=
0
self
.
dma_csr
.
wr_bit
(
self
.
R_DMA_CTL
,
self
.
DMA_CTL_ABORT
,
1
)
# The following two lines should be removed
# when the GN4124 vhdl core will implement auto clear of start bit
while
(
'Aborted'
!=
self
.
get_dma_status
()):
pass
self
.
dma_csr
.
wr_bit
(
self
.
R_DMA_CTL
,
self
.
DMA_CTL_ABORT
,
0
)