Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
P
python_test_scripts
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Jira
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
LOFAR2.0
python_test_scripts
Commits
8ecf836e
Commit
8ecf836e
authored
Jan 6, 2023
by
Gijs Schoonderbeek
Browse files
Options
Downloads
Patches
Plain Diff
Added test functionality, not tested on HW yet.
parent
b7b9a175
Branches
Branches containing commit
No related tags found
1 merge request
!3
Apsct production
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
APSCT_I2C.py
+61
-0
61 additions, 0 deletions
APSCT_I2C.py
apsct_lib.py
+93
-53
93 additions, 53 deletions
apsct_lib.py
production_apsct.py
+39
-28
39 additions, 28 deletions
production_apsct.py
with
193 additions
and
81 deletions
APSCT_I2C.py
0 → 100644
+
61
−
0
View file @
8ecf836e
"""
Copyright 2022 Stichting Nederlandse Wetenschappelijk Onderzoek Instituten,
ASTRON Netherlands Institute for Radio Astronomy
Licensed under the Apache License, Version 2.0 (the
"
License
"
);
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an
"
AS IS
"
BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Created: 2022-12-07
This file contains the definitions of the APSPU registers etc.
"""
#
# I2C address, registers and ports for APSCT
# Created: 2023-01-06
#
#
# Power supplies
#
PWR_LOCATIONS
=
{
"
INPUT
"
:
0
,
"
PLL_160M
"
:
1
,
"
PLL_200M
"
:
2
,
"
DIST_A
"
:
3
,
"
DIST_B
"
:
4
,
"
DIST_C
"
:
5
,
"
DIST_D
"
:
6
,
"
CTRL
"
:
7
}
PWR_VOUT
=
{
"
INPUT
"
:
3.3
,
"
PLL_160M
"
:
3.3
,
"
PLL_200M
"
:
3.3
,
"
DIST_A
"
:
3.3
,
"
DIST_B
"
:
3.3
,
"
DIST_C
"
:
3.3
,
"
DIST_D
"
:
3.3
,
"
CTRL
"
:
3.3
}
#
# PLL constants / pin locations
#
CS
=
6
SCLK
=
4
SDO
=
5
SDI
=
7
PLL_200M
=
0x20
PLL_160M
=
0x21
#
# Central I2C Devices
#
EEPROM
=
0x50
This diff is collapsed.
Click to expand it.
apsct_lib.py
+
93
−
53
View file @
8ecf836e
...
...
@@ -15,6 +15,7 @@ Set APSCT_CLK
"""
import
sys
import
APSCT_I2C
import
time
sys
.
path
.
insert
(
0
,
'
.
'
)
import
os
...
...
@@ -26,26 +27,17 @@ else:
I2CBUSNR
=
5
sleep_time
=
0.15
EEPROM
=
0x50
PLL_200M
=
0x20
PLL_160M
=
0x21
CS
=
6
SCLK
=
4
SDO
=
5
SDI
=
7
class
ApsctClass
:
#
# Toplevel class that contrains all parts of the APSCT
#
def
__init__
(
self
):
def
__init__
(
self
,
frequency
=
"
200MHz
"
):
self
.
status
=
False
self
.
frequency
=
frequency
self
.
eeprom
=
EepromClass
()
self
.
pll_200
=
PllClass
(
PLL_
200M
)
self
.
pll_160
=
PllClass
(
PLL_
160M
)
self
.
pll_200
=
PllClass
(
"
200M
Hz
"
)
self
.
pll_160
=
PllClass
(
"
160M
Hz
"
)
self
.
sensors
=
ApsctSensors
()
def
read_IO_expanderis
(
self
):
...
...
@@ -76,13 +68,13 @@ class ApsctClass:
I2C_IO_device_B
=
I2C
(
0x21
,
BUSNR
=
I2CBUSNR
)
I2C_IO_device_B
.
write_bytes
(
0x06
,
0x2C
)
# '0' is output
if
state
:
bits_to_set_A1
=
0x02
|
(
1
<<
CS
)
|
(
0
<<
SCLK
)
|
(
0
<<
SDI
)
bits_to_set_A1
=
0x02
|
(
1
<<
APSCT_I2C
.
CS
)
|
(
0
<<
APSCT_I2C
.
SCLK
)
|
(
0
<<
APSCT_I2C
.
SDI
)
bits_to_set_A2
=
0x04
bits_to_set_B1
=
0x02
|
(
1
<<
CS
)
|
(
0
<<
SCLK
)
|
(
0
<<
SDI
)
bits_to_set_B1
=
0x02
|
(
1
<<
APSCT_I2C
.
CS
)
|
(
0
<<
APSCT_I2C
.
SCLK
)
|
(
0
<<
APSCT_I2C
.
SDI
)
else
:
bits_to_set_A1
=
0x00
|
(
1
<<
CS
)
|
(
0
<<
SCLK
)
|
(
0
<<
SDI
)
bits_to_set_A1
=
0x00
|
(
1
<<
APSCT_I2C
.
CS
)
|
(
0
<<
APSCT_I2C
.
SCLK
)
|
(
0
<<
APSCT_I2C
.
SDI
)
bits_to_set_A2
=
0x00
bits_to_set_B1
=
0x00
|
(
1
<<
CS
)
|
(
0
<<
SCLK
)
|
(
0
<<
SDI
)
bits_to_set_B1
=
0x00
|
(
1
<<
APSCT_I2C
.
CS
)
|
(
0
<<
APSCT_I2C
.
SCLK
)
|
(
0
<<
APSCT_I2C
.
SDI
)
if
DEBUG
:
stri
=
"
Bits to reg 0 0x{0:x}
"
.
format
(
bits_to_set_A1
)
print
(
stri
)
...
...
@@ -90,32 +82,47 @@ class ApsctClass:
I2C_IO_device_A
.
write_bytes
(
0x03
,
bits_to_set_A2
)
I2C_IO_device_B
.
write_bytes
(
0x02
,
bits_to_set_B1
)
def
set_apsct
(
self
,
state
):
def
set_apsct
(
self
):
#
# set APSCT to 200MHz, 160MHz or off
#
if
s
tate
==
"
200MHz
"
:
if
s
elf
.
frequency
==
"
200MHz
"
:
self
.
power
(
True
)
self
.
pll_200
.
setup_pll
()
elif
s
tate
==
"
160MHz
"
:
elif
s
elf
.
frequency
==
"
160MHz
"
:
self
.
power
(
True
)
self
.
pll_160
.
setup_pll
()
else
:
self
.
power
(
False
)
def
check_apsct
(
self
):
result
=
self
.
sensors
.
check_values
()
if
self
.
frequency
==
"
200MHz
"
:
self
.
pll_200
.
read_lock
()
lock
=
self
.
pll_200
.
lock
result
=
result
&
lock
elif
self
.
frequency
==
"
160MHz
"
:
self
.
pll_160
.
read_lock
()
lock
=
self
.
pll_160
.
lock
result
=
result
&
lock
else
:
result
=
result
return
result
class
PllClass
:
#
# Toplevel class that contrains all parts of the PLL
#
def
__init__
(
self
,
address
=
0x20
):
def
__init__
(
self
,
frequency
=
"
200MHz
"
):
self
.
status
=
False
self
.
i2c_address
=
address
self
.
dev_i2c_pll
=
I2C
(
self
.
i2c_address
,
BUSNR
=
I2CBUSNR
)
if
address
==
0x20
:
self
.
frequency
=
'
200MHz
'
self
.
lock
=
False
self
.
frequency
=
frequency
if
self
.
frequency
==
"
160MHz
"
:
self
.
i2c_address
=
APSCT_I2C
.
PLL_160M
else
:
self
.
frequency
=
'
160MHz
'
self
.
i2c_address
=
APSCT_I2C
.
PLL_200M
self
.
dev_i2c_pll
=
I2C
(
self
.
i2c_address
,
BUSNR
=
I2CBUSNR
)
def
Write_byte_PLL
(
self
,
reg_address
,
wr_data
):
#
...
...
@@ -131,19 +138,19 @@ class PllClass:
print
(
stri
)
data
=
(
reg_address
<<
9
)
+
(
pll_rw
<<
8
)
+
wr_data
bit_array
=
"
{0:{fill}16b}
"
.
format
(
data
,
fill
=
'
0
'
)
self
.
dev_i2c_pll
.
write_bytes
(
0x02
,
0x02
|
(
0x1
<<
CS
))
self
.
dev_i2c_pll
.
write_bytes
(
0x02
,
0x02
|
(
0x1
<<
APSCT_I2C
.
CS
))
for
bit
in
bit_array
:
for
clk
in
range
(
2
):
Write_data
=
0x02
|
(
0
<<
CS
)
|
(
clk
<<
SCLK
)
|
(
int
(
bit
)
<<
SDI
)
Write_data
=
0x02
|
(
0
<<
APSCT_I2C
.
CS
)
|
(
clk
<<
APSCT_I2C
.
SCLK
)
|
(
int
(
bit
)
<<
APSCT_I2C
.
SDI
)
self
.
dev_i2c_pll
.
write_bytes
(
0x02
,
Write_data
)
for
clk
in
range
(
2
):
Write_data
=
0x02
|
(
0
<<
CS
)
|
(
clk
<<
SCLK
)
Write_data
=
0x02
|
(
0
<<
APSCT_I2C
.
CS
)
|
(
clk
<<
APSCT_I2C
.
SCLK
)
self
.
dev_i2c_pll
.
write_bytes
(
0x02
,
Write_data
)
for
clk
in
range
(
2
):
Write_data
=
0x02
|
(
1
<<
CS
)
|
(
clk
<<
SCLK
)
Write_data
=
0x02
|
(
1
<<
APSCT_I2C
.
CS
)
|
(
clk
<<
APSCT_I2C
.
SCLK
)
self
.
dev_i2c_pll
.
write_bytes
(
0x02
,
Write_data
)
Write_data
=
0x02
|
(
1
<<
CS
)
|
(
0
<<
SCLK
)
|
(
0
<<
SDI
)
Write_data
=
0x02
|
(
1
<<
APSCT_I2C
.
CS
)
|
(
0
<<
APSCT_I2C
.
SCLK
)
|
(
0
<<
APSCT_I2C
.
SDI
)
self
.
dev_i2c_pll
.
write_bytes
(
0x02
,
Write_data
)
def
Read_byte_PLL
(
self
,
reg_address
,
nof_bytes
=
1
):
...
...
@@ -156,21 +163,22 @@ class PllClass:
bit_array
=
"
{0:{fill}8b}
"
.
format
(
data
,
fill
=
'
0
'
)
for
bit
in
bit_array
:
for
clk
in
range
(
2
):
Write_data
=
0x02
|
(
0
<<
CS
)
|
(
clk
<<
SCLK
)
|
(
int
(
bit
)
<<
SDI
)
Write_data
=
0x02
|
(
0
<<
APSCT_I2C
.
CS
)
|
(
clk
<<
APSCT_I2C
.
SCLK
)
|
(
int
(
bit
)
<<
APSCT_I2C
.
SDI
)
self
.
dev_i2c_pll
.
write_bytes
(
0x02
,
Write_data
)
sleep
(
sleep_time
)
read_bit
=
''
for
cnt
in
range
(
8
*
nof_bytes
):
for
clk
in
[
0
,
1
]:
# Read after rizing edge
Write_data
=
0x02
|
(
clk
<<
SCLK
)
|
(
int
(
bit_array
[
-
1
])
<<
SDI
)
Write_data
=
0x02
|
(
clk
<<
APSCT_I2C
.
SCLK
)
|
(
int
(
bit_array
[
-
1
])
<<
APSCT_I2C
.
SDI
)
self
.
dev_i2c_pll
.
write_bytes
(
0x02
,
Write_data
)
ret_ack
,
ret_value
=
self
.
dev_i2c_pll
.
read_bytes
(
0x00
,
1
)
if
ret_ack
:
read_bit
+=
str
((
int
(
ret_value
,
16
)
>>
SDO
)
&
0x01
)
read_bit
+=
str
((
int
(
ret_value
,
16
)
>>
APSCT_I2C
.
SDO
)
&
0x01
)
else
:
print
(
"
ACK nok
"
)
Write_data
=
0x02
|
(
1
<<
CS
)
|
(
0
<<
SCLK
)
|
(
0
<<
SDI
)
Write_data
=
0x02
|
(
1
<<
APSCT_I2C
.
CS
)
|
(
0
<<
APSCT_I2C
.
SCLK
)
|
(
0
<<
APSCT_I2C
.
SDI
)
self
.
dev_i2c_pll
.
write_bytes
(
0x02
,
Write_data
)
if
DEBUG
:
stri
=
"
Read back at address 0x{0:{fill}2x} result : 0x{1:{fill}2x}
"
.
format
(
reg_address
,
int
(
read_bit
,
2
),
fill
=
'
0
'
)
print
(
stri
)
...
...
@@ -226,13 +234,19 @@ class PllClass:
ret_value
=
self
.
Read_byte_PLL
(
0x00
,
nof_bytes
=
1
)
status_pll
=
int
(
ret_value
,
2
)
if
status_pll
==
0x04
:
self
.
lock
=
True
if
DEBUG
:
print
(
"
PLL in lock
"
)
elif
(
status_pll
&
0x10
)
>
0
:
self
.
lock
=
False
if
DEBUG
:
print
(
"
Not Locked --> No 10 MHz ref
"
)
else
:
self
.
lock
=
False
if
DEBUG
:
print
(
"
Not locked --> PLL Error
"
)
def
read_lol
(
self
,
pll_frequency
=
'
200MHz
'
):
def
read_lol
(
self
):
#
# Read loss of lock status
#
...
...
@@ -245,9 +259,9 @@ class PllClass:
ack
,
ret_value
=
I2C_IO_device_B
.
read_bytes
(
0x01
,
1
)
status_reg
=
int
(
ret_value
,
16
)
if
(
pll_
frequency
==
'
200MHz
'
)
&
((
status_reg
&
0x10
)
>
0
):
if
(
self
.
frequency
==
'
200MHz
'
)
&
((
status_reg
&
0x10
)
>
0
):
print
(
"
200MHz has lost lock
"
)
if
((
status_reg
&
0x20
)
>
0
)
&
(
pll_
frequency
==
'
160MHz
'
):
if
((
status_reg
&
0x20
)
>
0
)
&
(
self
.
frequency
==
'
160MHz
'
):
print
(
"
160MHz has last lock
"
)
ack
,
ret_value
=
I2C_IO_device_A
.
read_bytes
(
0x01
,
1
)
old_reg
=
int
(
ret_value
,
16
)
...
...
@@ -264,7 +278,7 @@ class EepromClass:
#
# All monitor. read and write functions for the EEPROM
#
self
.
dev_i2c_eeprom
=
I2C
(
EEPROM
)
self
.
dev_i2c_eeprom
=
I2C
(
APSCT_I2C
.
EEPROM
)
self
.
dev_i2c_eeprom
.
bus_nr
=
I2CBUSNR
def
write_eeprom
(
self
,
data
=
"
APSPU
"
,
address
=
0
):
...
...
@@ -301,7 +315,6 @@ class EepromClass:
else
:
ret_ack
,
ret_value
=
self
.
dev_i2c_eeprom
.
read_bytes
(
address
,
nof_bytes
)
ret_value
=
bytes
.
fromhex
(
ret_value
[:
nof_bytes
*
2
])
#print(" ret value = {}".format(ret_value))
str_return
=
ret_value
.
decode
(
'
UTF-8
'
)
return
str_return
...
...
@@ -334,12 +347,39 @@ class ApsctSensors:
#
self
.
dev_i2c_sensor
=
I2C
(
0x74
)
self
.
dev_i2c_sensor
.
bus_nr
=
I2CBUSNR
self
.
power_supplies
=
list
(
APSCT_I2C
.
PWR_LOCATIONS
.
keys
())
self
.
voltages
=
{}
self
.
temperature
=
9999
def
apsct_sensors
(
self
):
for
sens_line
in
range
(
7
):
self
.
read_voltage
(
sens_line
)
self
.
read_temp
()
def
read_all_voltages
(
self
):
for
pwr
in
self
.
power_supplies
:
self
.
voltages
[
pwr
]
=
self
.
read_voltage
(
APSCT_I2C
.
PWR_LOCATIONS
[
pwr
])
return
True
def
check_values
(
self
):
#
# Function to check sensor values
#
# return result, True when OK, False in case of error
#
result
=
True
self
.
read_all_voltages
()
self
.
read_temp
()
for
pwr
in
self
.
power_supplies
:
expected
=
APSCT_I2C
.
PWR_VOUT
[
pwr
]
if
0.9
*
expected
>
self
.
voltages
[
pwr
]
>
1.1
*
expected
:
result
=
False
print
(
f
"
Error
{
pwr
}
expected
{
expected
}
V read
{
self
.
voltages
[
pwr
]
}
V
"
)
if
15
>
self
.
temperature
>
50
:
result
=
False
print
(
f
"
Error temperature read
{
self
.
temperature
}
°C
"
)
return
result
def
read_voltage
(
self
,
input_channel
=
0
):
#
# Function to read a voltages of APSCT
...
...
@@ -347,6 +387,7 @@ class ApsctSensors:
# input_channel = sens port
# return value
#
voltage
=
9999
Vref
=
3.0
one_step
=
Vref
/
(
2
**
16
)
channel_select_word
=
0xB0
|
((
input_channel
%
2
)
<<
3
)
|
((
input_channel
>>
1
)
&
0x7
)
...
...
@@ -368,6 +409,7 @@ class ApsctSensors:
voltage
=
((
4.7
+
2.2
)
/
2.2
)
*
2
*
voltage
string
=
"
Voltage sens line {1} is {0:.4f} V
"
.
format
(
voltage
,
input_channel
)
print
(
string
)
return
voltage
def
read_temp
(
self
):
#
...
...
@@ -384,9 +426,7 @@ class ApsctSensors:
if
ret_ack
:
raw_value
=
(
int
(
ret_value
,
16
)
&
0x1FFFFF
)
>>
6
temperature_K
=
(
raw_value
/
temp_slope
)
temperature
=
temperature_K
-
273
stri
=
"
Temperature : {0:.2f} gr. C
"
.
format
(
temperature
)
print
(
stri
)
self
.
temperature
=
temperature_K
-
273
else
:
print
(
"
Error reading
tempeature
"
)
self
.
tempe
r
ature
=
9999
return
self
.
temperature
This diff is collapsed.
Click to expand it.
production_apsct.py
+
39
−
28
View file @
8ecf836e
...
...
@@ -11,49 +11,60 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Set
APSCT_CLK
Check
APSCT_CLK
"""
import
time
import
apsct_lib
import
sys
DEBUG
=
False
SET_PLL
=
True
READ_LOCK
=
True
READ_ALL
=
True
CHECK_EEPROM
=
True
PWR_RST
=
False
# True
READ_SENSOR
=
True
READ_REGS
=
False
# True
CLK_FREQ
=
'
200MHz
'
apsct
=
apsct_lib
.
ApsctClass
()
apsct
.
sensors
.
read_temp
()
if
len
(
sys
.
argv
)
<
2
:
print
(
"
Production_apsct.py <ASTRON NR> <Serial number>
"
)
print
(
"
e.g. python3 production_apsct.py 2023-01 1234
"
)
exit
()
if
CHECK_EEPROM
:
apsct
.
eeprom
.
wr_rd_eeprom
()
apsct
=
apsct_lib
.
ApsctClass
(
CLK_FREQ
)
if
PWR_RST
:
apsct
.
power
(
False
)
time
.
sleep
(
10
)
apsct
.
power
(
True
)
if
SET_PLL
:
apsct
.
set_apsct
(
CLK_FREQ
)
print
*
(
"
Check APSCT in 200MHz mode
"
)
apsct
.
frequency
=
"
200MHz
"
apsct
.
set_apsct
()
apsct
.
pll_200
.
read_lock
()
apsct
.
pll_200
.
read_lol
()
apsct
.
pll_160
.
read_lock
()
apsct
.
pll_160
.
read_lol
()
apsct
.
sensors
.
apsct_sensors
()
if
READ_LOCK
:
print
*
(
"
Check APSCT in 160MHz mode
"
)
apsct
.
frequency
=
"
160MHz
"
apsct
.
set_apsct
()
apsct
.
pll_200
.
read_lock
()
apsct
.
pll_200
.
read_lol
()
apsct
.
pll_160
.
read_lock
()
apsct
.
pll_160
.
read_lol
()
apsct
.
sensors
.
apsct_sensors
()
if
READ_REGS
:
apsct
.
pll_200
.
read_all_regs_pll
()
print
*
(
"
Check APSCT in off mode
"
)
apsct
.
frequency
=
"
OFF
"
apsct
.
set_apsct
()
apsct
.
pll_200
.
read_lock
()
apsct
.
pll_200
.
read_lol
()
apsct
.
pll_160
.
read_lock
()
apsct
.
pll_160
.
read_lol
()
apsct
.
sensors
.
apsct_sensors
()
if
READ_ALL
:
apsct
.
pll_200
.
read_all_regs_pll
()
# apsct.pll_160.read_all_regs_pll()
apsct
.
read_IO_expanderis
()
if
READ_SENSOR
:
apsct
.
sensors
.
apsct_sensors
()
apsct
.
pll_200
.
read_lol
(
CLK_FREQ
)
if
apsct
.
check_apsct
():
apsct_id
=
"
APSCT-
"
+
sys
.
argv
[
1
]
serial
=
sys
.
argv
[
2
]
rw_ok
=
apsct
.
eeprom
.
wr_rd_eeprom
(
apsct_id
,
address
=
0
)
if
rw_ok
:
rw_ok
=
apsct
.
eeprom
.
wr_rd_eeprom
(
serial
,
address
=
0x20
)
if
not
rw_ok
:
print
(
"
EEPROM Error
"
)
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment