Skip to content
Snippets Groups Projects
Commit 00de414f authored by Gijs Schoonderbeek's avatar Gijs Schoonderbeek
Browse files

Merge branch 'master' into 'APSPU_production'

# Conflicts:
#   APSPU_I2C.py
parents 9e461080 fc87ff1d
Branches
No related tags found
1 merge request!5Update text to close APSPU_production modifications.
......@@ -26,7 +26,7 @@ else:
DEBUG = False
I2CBUSNR=5
sleep_time = 0.15
SET_PLL = False #True
SET_PLL = True
READ_LOCK = True
READ_ALL = False
CHECK_EEPROM = False
......
"""
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
#
# I2C switch addresses
#
i2c_switch_addr_rcu = [0x70, 0x71, 0x72, 0x73]
i2c_bus_rcu = 1
i2c_switch_addr_unb = [0x70]
i2c_bus_unb = 3
#
# ID Pins
#
ID_PINS = [8, 7, 12, 16, 20, 21]
#******************************************#
# I2C address, registers and ports for UNB2c
# Created: 2021-05-11
# Last update 2023-01-27 for L2TS production series
#******************************************#
###################################
"""
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 APSPU
# Created: 2022-12-07
#
#
# General, Point of load converters
###################################
#
CTR_LBA = 0x3C
CTR_RCU2_A = 0x3D
......@@ -19,14 +37,14 @@ VOUT_POLS = {"CTR_LBA" : 8.0,
"CTR_RCU2_A": 5.60009765625,
"CTR_RCU2_D": 3.2998046875}
IOUT_POLS = {"CTR_LBA" : 0.45,
"CTR_RCU2_A" : 0.7,
"CTR_RCU2_D" : 0.3}
IOUT_POLS = {"CTR_LBA": 0.2,
"CTR_RCU2_A": 0.6,
"CTR_RCU2_D": 0.2}
LP_VIN = 0x88 #
LP_VIN = 0x88
LP_VOUT_MODE = 0x20
LP_VOUT = 0x8B #
LP_temp = 0x8D #
LP_VOUT = 0x8B
LP_temp = 0x8D
LP_IOUT = 0x8C
LP_VOUT_COMMAND = 0x21
LP_VOUT_TRIM = 0x22
......@@ -38,15 +56,16 @@ LP_VOUT_UV_LIMIT = 0x44
LP_STORE_USER_ALL = 0x15
LP_ON_OFF_CONFIG = 0x02
LP_OPERATION = 0x01
###################################
LP_WRITE_PROTECT = 0x10
LP_STORE_DEFAULT_ALL = 0x12
#
# Central I2C Devices
###################################
#
EEPROM = 0x50
###################################
#
# FAN speed
###################################
#
MAX6620 = 0x29
REG_GLOBAL = 0x00
......@@ -57,15 +76,20 @@ TACH_COUNT_FREQ = 8192
FAN_TACHS = 1
RUN_MONITOR = 0x02
NOF_APS_FANS = 3
######################
#
# Functions
######################
#
# Calculate floating point value according PMBus lineair
def calc_lin_2bytes(data):
#
# Calculate floating point value according PMBus lineair
#
# input data (Byte array)
# return value (float)
#
expo = ((data[1] & 0xf8) >> 3)
if expo == 1:
expo = -7
......@@ -77,14 +101,17 @@ def calc_lin_2bytes(data):
output = mantisse * 2**expo
return output
# Calculate floating point value according PMBus lineair
def calc_lin_3bytes(data, mode):
#
# Calculate floating point value according PMBus lineair
#
# input data (Byte array)
# return value (float)
#
expo = (mode[0] & 0x1F)
if expo > 2**4:
expo = expo - 2**5
mant = (data[1]*256 + data[0])
output = mant * 2**expo
return output
......@@ -42,15 +42,20 @@ class I2C:
ret_ack = 1
if SLOW:
sleep(0.2)
except IOError, err:
except IOError:
ret_ack = 0
ret_value = 'ffff'
if DEBUG:
print("Reading error")
except err:
ret_ack = 0
ret_value = 'ffff'
if DEBUG:
print("Reading IO-error")
return ret_ack, ret_value
def read_last_reg(self, bytes_to_read):
def read_last_reg(self, bytes_to_read, print_on = DEBUG):
bus = smbus.SMBus(self.bus_nr)
rd_value = []
ret_value = ''
......@@ -60,10 +65,15 @@ class I2C:
ret_ack = 1
if SLOW:
sleep(0.2)
except IOError, err:
except IOError:
ret_ack = 0
rd_value.append(0)
if DEBUG:
if print_on:
print(f"Reading IOerror {rd_value}")
except err:
ret_ack = 0
rd_value.append(0)
if print_on:
print("Reading error")
for cnt in range(bytes_to_read):
ret_value += (hex(rd_value[cnt])[2:])
......@@ -71,16 +81,23 @@ class I2C:
def write_bytes(self, register, data):
bus = smbus.SMBus(self.bus_nr)
if type(data) is not list:
data = [data]
try:
bus.write_i2c_block_data(self.I2C_Address, register, [data])
bus.write_i2c_block_data(self.I2C_Address, register, data)
ret_ack = 1
if SLOW:
sleep(0.3)
except IOError, err:
except IOError:
ret_ack = 0
ret_value = 0
if DEBUG:
print("Write error")
except err:
ret_ack = 0
ret_value = 0
if DEBUG:
print("Write IO-error")
return ret_ack
def write_register(self, register):
......@@ -90,11 +107,16 @@ class I2C:
ret_ack = 1
if SLOW:
sleep(0.3)
except IOError, err:
except IOError:
ret_ack = 0
ret_value = 0
if DEBUG:
print("Write error")
except err:
ret_ack = 0
ret_value = 0
if DEBUG:
print("Write IO-error")
return ret_ack
def write_pointer(self, register):
......@@ -104,11 +126,16 @@ class I2C:
ret_ack = 1
if SLOW:
sleep(0.3)
except IOError, err:
except IOError:
ret_ack = 0
ret_value = 0
if DEBUG:
print("Write error")
except err:
ret_ack = 0
ret_value = 0
if DEBUG:
print("Write IO-error")
return ret_ack
def ack_check(self):
......@@ -119,11 +146,16 @@ class I2C:
ret_ack = 1
if SLOW:
sleep(0.3)
except IOError, err:
except IOError:
ret_ack = 0
ret_value = 0
if DEBUG:
print("No ACK")
except err:
ret_ack = 0
ret_value = 0
if DEBUG:
print("No ACK IO-Error")
return ret_ack
if __name__ == "__main__":
......
......@@ -97,7 +97,8 @@ class I2C:
def write_pointer(self, register):
bus = pi.i2c_open(self.bus_nr, self.I2C_Address)
try:
pi.i2c_read_device(bus, 1)
# pi.i2c_read_device(bus, 1)
pi.i2c_read_device(bus, register)
ret_ack = 1
if SLOW:
sleep(0.3)
......@@ -109,6 +110,20 @@ class I2C:
pi.i2c_close(bus)
return ret_ack
def write_register(self, register):
bus = pi.i2c_open(self.bus_nr, self.I2C_Address)
try:
ret_value = pi.i2c_write_device(bus, [register])
ret_ack = 1
if SLOW:
sleep(0.3)
except IOError:
ret_ack = 0
ret_value = 0
if DEBUG:
print("No ACK")
return ret_ack
def ack_check(self):
bus = smbus.SMBus(self.bus_nr)
try:
......
'''
Copyright 2021 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.
I2C_serial_Pi
Started by Gijs
Class for using the I2C bus of the I2C. This class is used for the
basic I2C scripts to read and write the RCU2, PCC etc.
'''
import smbus2
import sys
from time import *
DEBUG = False #True
SLOW = False
class I2C:
def __init__(self, ADDRESS='040',BUSNR=3):
self.I2C_Address = ADDRESS
self.bus_nr = BUSNR
def close(self):
bus = smbus2.SMBus(self.bus_nr)
bus.close()
return True
def open(self):
bus = smbus2.SMBus(self.bus_nr)
bus.open(self.bus_nr)
return True
def read_bytes(self, register, bytes_to_read=2):
bus = smbus2.SMBus(self.bus_nr)
try:
rd_value = bus.read_i2c_block_data(self.I2C_Address, register, bytes_to_read)
ret_value = ''
for cnt in range(bytes_to_read):
ret_value += (hex(rd_value[cnt])[2:])
ret_ack = 1
if SLOW:
sleep(0.2)
except IOError:
ret_ack = 0
ret_value = 'ffff'
if DEBUG:
print("Reading IO-error")
return ret_ack, ret_value
def read_last_reg(self, bytes_to_read):
bus = smbus2.SMBus(self.bus_nr)
rd_value = []
ret_value = ''
for cnt in range(bytes_to_read):
try:
rd_value.append(bus.read_byte(self.I2C_Address))
ret_ack = 1
if SLOW:
sleep(0.2)
except IOError:
ret_ack = 0
rd_value.append(0)
if DEBUG:
print("IO-Reading error")
for cnt in range(bytes_to_read):
ret_value += (hex(rd_value[cnt])[2:])
return ret_ack,ret_value
def write_bytes(self, register, data):
bus = smbus2.SMBus(self.bus_nr)
if type(data) is not list:
data = [data]
try:
bus.write_i2c_block_data(self.I2C_Address, register, data)
ret_ack = 1
if SLOW:
sleep(0.3)
except IOError:
ret_ack = 0
ret_value = 0
if DEBUG:
print("Write IO-error")
return ret_ack
def write_register(self, register):
bus = smbus2.SMBus(self.bus_nr)
try:
bus.write_byte(self.I2C_Address, register)
# print(f"Wrote {register:x}")
ret_ack = 1
if SLOW:
sleep(0.3)
except IOError:
ret_ack = 0
ret_value = 0
# if DEBUG:
print("Write IO-error")
return ret_ack
def write_pointer(self, register):
bus = smbus2.SMBus(self.bus_nr)
try:
ret_value = bus.read_i2c_block_data(self.I2C_Address, register, 1)
ret_ack = 1
if SLOW:
sleep(0.3)
except IOError:
ret_ack = 0
ret_value = 0
if DEBUG:
print("Write IO-error")
return ret_ack
def ack_check(self):
bus = smbus2.SMBus(self.bus_nr)
try:
print("check ACK")
ret_value = bus.write_quick(self.I2C_Address)
ret_ack = 1
if SLOW:
sleep(0.3)
except IOError:
ret_ack = 0
ret_value = 0
if DEBUG:
print("No ACK IO-Error")
return ret_ack
if __name__ == "__main__":
I2C_Device = I2C(0x40)
I2C_Device.write_bytes(0x00, 0x00)
ret_ack, ret_value = I2C_Device.read_bytes(0x8C, 2)
print(ret_value)
This diff is collapsed.
......@@ -12,8 +12,8 @@ See the License for the specific language governing permissions and
limitations under the License.
Created: 2021-05-10
This file contains the UniBoard2 class with all monitoring function. It can be used stand-alone to test it.
Created: 2022-17-12
This file contains the APSPU class with all monitoring function. It can be used stand-alone to test it.
"""
......@@ -21,20 +21,21 @@ import sys
sys.path.insert(0, '.')
import os
import math
from APSPU_I2C import *
if os.name == "posix":
from I2C_serial_pi2 import *
from I2C_serial_pi3 import *
else:
from I2C_serial import *
I2CBUSNR = 1
DEBUG = False
I2CBUSNR = 1 # Bus used on the Pi
DEBUG = False # Set True to print debug information on the screen
I_OK_MARGIN = 0.5 # I_error in Amps
class ApspuClass:
#
# Class that contains all parts on a UniBoard2
# Toplevel Class that contains all parts on a APSU
#
def __init__(self):
self.status = False
......@@ -46,7 +47,7 @@ class ApspuClass:
def read_all(self):
#
# Function to read all monitoring points of the UniBoard
# Function to read all monitoring points of the APSPU
#
print("--------- \nRead APSPU Status\n---------")
for pol in self.pols:
......@@ -64,24 +65,41 @@ class ApspuClass:
return True
def set_pols(self):
#
# Function to set output voltage level on the APSPU
# Values are read from the APSPU_I2C
#
print("--------- \nProgram Pols\n---------")
for pol in self.pols:
pol.set_vout_pol(VOUT_POLS[pol.name])
vout = pol.read_vout_set()
if not (0.9*VOUT_POLS[pol.name] < vout < 1.1*VOUT_POLS[pol.name]):
print(f"POL {pol.name:10} Error setting Vout, "
f"set to {VOUT_POLS[pol.name]} read back {vout}")
exit()
pol.set_vout_ov_limit_pol(1.2*VOUT_POLS[pol.name])
ov_out = pol.read_ov_limit()
if not (1.1*VOUT_POLS[pol.name] < ov_out < 1.3*VOUT_POLS[pol.name]):
print(f"POL {pol.name:10} Error setting output overvoltage"
f"set {1.2*VOUT_POLS[pol.name]} read back {ov_out}")
exit()
pol.set_on_off_config()
if DEBUG:
pol.read_vout_set()
pol.read_ov_limit()
pol.read_uv_limit()
pol.on_off(True)
pol.write_to_nvm()
print("Done")
def check_apspu(self):
#
# Function to check values of read_all() Used during production
#
# Return True is OK, False if not OK
#
print("--------- \nCheck APSPU \n---------")
check_ok = True
for pol in self.pols:
check_ok = check_ok & pol.check_pol()
check_ok = check_ok & self.fans.check_fans()
check_ok = check_ok & self.eeprom.wr_rd_eeprom(value="PROD_CHECK", address=0x30)
if check_ok:
print("APSPU OK")
else:
......@@ -89,6 +107,12 @@ class ApspuClass:
return check_ok
def apspu_on_off(self, on):
#
# Function to switch off the POLs on APSPU
# on = True to switch APSU on
# on = False to switch APSU off
# Return: always True
#
if on:
print(f">> Switch APSPU ON")
else:
......@@ -97,13 +121,14 @@ class ApspuClass:
pol.on_off(on)
return True
class EepromClass:
#
# Class to handle EEPROM communication
#
def __init__(self):
#
# All monitoring points Point of Load DC/DC converter
# All monitor. read and write functions for the EEPROM
#
self.dev_i2c_eeprom = I2C(EEPROM)
self.dev_i2c_eeprom.bus_nr = I2CBUSNR
......@@ -112,6 +137,10 @@ class EepromClass:
#
# Write the EEPROM with the serial number etc.
#
# Data = data to write in string formal
# Address = address to write the data to
# Return True if successfully
#
ret_ack, ret_value = self.dev_i2c_eeprom.read_bytes(0)
if ret_ack < 1:
print("EEPROM not found during write")
......@@ -127,6 +156,10 @@ class EepromClass:
#
# Read the EEPROM with the serial number etc.
#
# Address = address to read from
# nof_bytes = number of bytes to read
# return string with the data from the flash
#
ret_ack, ret_value = self.dev_i2c_eeprom.read_last_reg(1)
if ret_ack < 1:
print("no EEPROM found during read")
......@@ -140,11 +173,18 @@ class EepromClass:
#
# Write and Read the EEPROM to check functionality
#
# value = string with data to write
# address = address to write the data to
# return True if read back is same as write value
#
if self.write_eeprom(value, address=0):
ret_value = self.read_eeprom(address=0, nof_bytes=len(value))
stri = "Wrote to EEPROM register 0x{2:x} : {0}, Read from EEPROM: {1}".format(value, ret_value, address)
print(stri)
if ret_value == value:
return True
else:
return False
class PolClass:
......@@ -170,16 +210,16 @@ class PolClass:
else:
self.status = True
def read_vout_set(self):
#
# Function to read the output voltage of the Point of Load DC/DC converter
#
# Return: output value is of else 999
#
if self.status:
ret_ack, raw_value = self.pol_dev.read_bytes(LP_VOUT_COMMAND, 2)
if len(raw_value) < 4:
raw_value = '0' + raw_value
ret_value = []
ret_value = int(raw_value[2:], 16) * 2**8
ret_value += int(raw_value[:2], 16)
output_value = ret_value * 2**-11
......@@ -193,6 +233,9 @@ class PolClass:
#
# Function to set the output of the DC/DC converter
#
# Return always I2C ack
#
ret_ack = False
if self.status:
if DEBUG:
ret_ack, raw_value = self.pol_dev.read_bytes(LP_ON_OFF_CONFIG, 1)
......@@ -204,17 +247,30 @@ class PolClass:
default_off = 1 << 4
wr_data = on_off_bit + polarity_pin + use_external + use_soft + default_off
ret_ack = self.pol_dev.write_bytes(LP_ON_OFF_CONFIG, wr_data)
return True
return ret_ack
def on_off(self, on=True):
#
# Function to switch on or off a POL
#
# if on = True switch on the POL
# if on = Flase swtich off the POL
# Return I2C ack
#
wr_data = (on << 7) + 0
ret_ack = self.pol_dev.write_bytes(LP_OPERATION, wr_data)
return ret_ack
def set_vout_pol(self, value):
#
# Function to read the output voltage of the Point of Load DC/DC converter
#
# value is the output voltage level in V
# return I2C ack
#
ret_ack = False
if self.status:
ret_ack = self.pol_dev.write_bytes(LP_WRITE_PROTECT, [0])
set_value = int(value * (2**11))
hex_set_value = hex(set_value)
wr_value = (hex_set_value[4:6] + hex_set_value[2:4])
......@@ -224,12 +280,16 @@ class PolClass:
wr_data.append(int(hex_set_value[4:6], 16))
wr_data.append(int(hex_set_value[2:4], 16))
ret_ack = self.pol_dev.write_bytes(LP_VOUT_COMMAND, wr_data)
return True
return ret_ack
def set_vout_ov_limit_pol(self, value):
#
# Function to read the output voltage of the Point of Load DC/DC converter
#
# value is the overvoltage level of the output
# return I2C ack
#
ret_ack = False
if self.status:
set_value = int(value * (2**11))
hex_set_value = hex(set_value)
......@@ -240,10 +300,24 @@ class PolClass:
wr_data.append(int(hex_set_value[4:6], 16))
wr_data.append(int(hex_set_value[2:4], 16))
ret_ack = self.pol_dev.write_bytes(LP_VOUT_OV_LIMIT, wr_data)
return True
return ret_ack
def write_to_nvm(self):
ret_ack = self.pol_dev.write_bytes(LP_STORE_USER_ALL, 0)
#
# Function to write the POL's registers to NVM memory
#
# return is always True
#
print(f"Store to NVM for POL {self.name}")
if False:
ret_ack = self.pol_dev.write_register(0x15)
sleep(1)
else:
self.pol_dev.close()
command = f"i2cset -y 1 0x{CTR_POLS[self.name]:02X} 0x15 cp"
os.system(command)
os.system(command)
self.pol_dev.open()
return True
def read_vin(self):
......@@ -252,13 +326,17 @@ class PolClass:
#
if self.status:
ret_ack, raw_value = self.pol_dev.read_bytes(LP_VIN, 2)
if not ret_ack:
self.iout=999
return False
if len(raw_value) < 4:
raw_value = '0' + raw_value
ret_value = []
ret_value.append(int(raw_value[:2], 16))
ret_value.append(int(raw_value[2:], 16)) # * 2**8
output_value = calc_lin_2bytes(ret_value) #ret_value * 2**-11
ret_value.append(int(raw_value[2:], 16))
output_value = calc_lin_2bytes(ret_value)
self.vin = output_value
return True
def read_vout(self):
#
......@@ -266,7 +344,13 @@ class PolClass:
#
if self.status:
ret_ack, vout_mod = self.pol_dev.read_bytes(LP_VOUT_MODE, 1)
if not ret_ack:
self.vout=999
return False
ret_ack, raw_value = self.pol_dev.read_bytes(LP_VOUT, 2)
if not ret_ack:
self.vout=999
return False
vout_mod = int(vout_mod, 16)
ret_value = []
ret_value.append(int(raw_value[:2], 16))
......@@ -275,27 +359,36 @@ class PolClass:
except:
ret_value.append(0)
self.vout = calc_lin_3bytes(ret_value, [vout_mod])
return True
else:
self.vout = 999
return False
def read_ov_limit(self):
#
# Function to read the output voltage of the Point of Load DC/DC converter
# and print on the screen
#
# Return OV limit
#
output_value = 0
if self.status:
ret_ack, raw_value = self.pol_dev.read_bytes(LP_VOUT_OV_LIMIT, 2)
if len(raw_value) < 4:
raw_value = '0' + raw_value
ret_value = []
ret_value = int(raw_value[2:], 16) * 2**8
ret_value += int(raw_value[:2], 16)
output_value = ret_value * 2**-11
if DEBUG:
print(f"Output OV limit is set to: = {output_value:5.2f} V using hex value {raw_value}")
return output_value
def read_uv_limit(self):
#
# Function to read the output voltage of the Point of Load DC/DC converter
#
# Return UV limit if OK else False
#
if self.status:
ret_ack, raw_value = self.pol_dev.read_bytes(LP_VOUT_UV_LIMIT, 2)
if len(raw_value) < 4:
......@@ -304,10 +397,11 @@ class PolClass:
ret_value = int(raw_value[2:], 16) * 2**8
ret_value += int(raw_value[:2], 16)
output_value = ret_value * 2**-11
if DEBUG:
print(f"Output UV limit is set to: = {output_value:5.2f} V using hex value {raw_value}")
return output_value
else:
return 9999
return False
def read_iout(self):
#
......@@ -346,6 +440,11 @@ class PolClass:
self.read_vin()
def check_pol(self):
#
# Function to read all monitoring points of the Point of Load DC/DC converter
#
# Return True if OK, False if not OK
#
self.read_all()
self.on_off(on=True)
check_ok = False
......@@ -372,16 +471,16 @@ class PolClass:
check_ok = False
print(f"POL {self.name:10} TEMP not OK, expected {temp_low} C - {temp_high} C, measured {self.temp} C ")
return check_ok
i_low = 0.75*IOUT_POLS[self.name]
i_high = 1.25*IOUT_POLS[self.name]
i_low = (1-I_OK_MARGIN)*IOUT_POLS[self.name]
i_high = (1+I_OK_MARGIN)*IOUT_POLS[self.name]
if i_low < self.iout < i_high:
check_ok = True
else:
check_ok = False
print(f"POL {self.name:10} Iout not OK, expected {i_low:4.2f} A - {i_high:4.2f} A, measured {self.iout:4.2f} A ")
print(f"POL {self.name:10} Iout not OK,"
f" expected {i_low:4.2f} A - {i_high:4.2f} A, measured {self.iout:4.2f} A ")
return check_ok
def print_status(self):
#
# Function to dump all monitoring points of the Point of Load DC/DC converter on the screen
......@@ -395,13 +494,14 @@ class PolClass:
print(stri)
self.read_vout_set()
class FanmonitorClass:
#
# Class to read all monitoring points Point of Load DC/DC converter
# Class to read all monitoring points fan units in the APS
#
def __init__(self):
#
# All monitoring points Point of Load DC/DC converter
# All monitoring points for the fans
#
self.rpm = []
self.fanmonitor_dev = I2C(MAX6620)
......@@ -426,7 +526,8 @@ class FanmonitorClass:
self.fanmonitor_dev.write_bytes(REG_GLOBAL, RUN_MONITOR)
ret_ack, reg_after = self.fanmonitor_dev.read_bytes(REG_GLOBAL, 1)
if DEBUG:
stri = "Reg at address 0x{0} before : {1} and after write action {2}".format(REG_GLOBAL, reg_before, reg_after)
stri = "Reg at address 0x{0} before : {1} and after write action {2}"\
.format(REG_GLOBAL, reg_before, reg_after)
print(stri)
fan_config_reg = int((math.log(TACH_PERIODS) / math.log(2))) << 5
for fan_cnt in range(NOF_APS_FANS):
......@@ -436,13 +537,16 @@ class FanmonitorClass:
def read_fan(self, fan_nr):
#
# Function to a single fan
# fan_nr is the fan to read ranging from 0 till 2
# return the speed of the fan
#
if fan_nr > NOF_APS_FANS:
return 0
ret_ack, tach_msb = self.fanmonitor_dev.read_bytes(REG_TACH_MSP_REGS[fan_nr], 1)
tach_msb = int(tach_msb, 16) & 0xFF
if tach_msb > 254:
if DEBUG :
tach_lsb = 255
tach = 99999
if tach_msb > 254:
rpm = 0
else:
ret_ack, tach_lsb = self.fanmonitor_dev.read_bytes(REG_TACH_LSP_REGS[fan_nr], 1)
......@@ -463,6 +567,9 @@ class FanmonitorClass:
self.rpm.append(self.read_fan(fan_counter))
def check_fans(self):
#
# Function to check fan speeds
#
self.read_all()
check_ok = True
for cnt, speed in enumerate(self.rpm):
......
"""
Copyright 2021 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.
Check APSCT_CLK
"""
import apsct_lib
import sys
READ_ALL = False # True
CLK_FREQ = '200MHz'
if len(sys.argv) < 2:
print("Production_apsct.py <ASTRON NR> <Serial number>")
print("e.g. python3 production_apsct.py 2023-01 1234")
exit()
apsct = apsct_lib.ApsctClass(CLK_FREQ)
state = True
modi = ["200MHz", "160MHz", "OFF"]
for mode in modi:
print(f"Check APSCT in {mode} mode")
apsct.frequency = mode
apsct.set_apsct()
if mode == "200MHz":
state = state & apsct.pll_200.read_lock()
if mode == "160MHz":
state = state & apsct.pll_160.read_lock()
apsct.frequency = "200MHz"
apsct.set_apsct()
apsct.pll_200.read_lock()
apsct.sensors.apsct_sensors()
state = state & apsct.check_apsct()
if READ_ALL:
apsct.pll_200.read_all_regs_pll()
apsct.pll_160.read_all_regs_pll()
apsct.read_io_expanderis()
if state:
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")
else:
print("\n >>> Errors during testing <<<\n")
"""
Copyright 2021 Stichting Nederlandse Wetenschappelijk Onderzoek Instituten,
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.
......@@ -12,17 +12,15 @@ See the License for the specific language governing permissions and
limitations under the License.
Created: 2021-05-10
This file contains the UniBoard2 class with all monitoring function. It can be used stand-alone to test it.
Created: 2022-12-07
This file contains the APSPU production script.
"""
import sys
sys.path.insert(0, '.')
import os
import math
from apspu_lib import *
from apspu_lib import *
if len(sys.argv) < 2:
......@@ -32,20 +30,18 @@ if len(sys.argv)<2:
apspu = ApspuClass()
apspu.apspu_on_off(False)
sleep(5)
sleep(5) # Wait for outputs to be stable off
apspu.set_pols()
x = input("Change dipswitches and press key to continue..")
input("Change dipswitches and press key to continue..")
apspu.apspu_on_off(True)
sleep(10)
sleep(5) # Wait for outputs to be stable on
apspu.read_all()
apspu.print_status()
if apspu.check_apspu():
apspu.apspu_on_off(False)
sleep(10)
apspu.read_all()
apspu.print_status()
apspu.apspu_on_off(True)
id = "APSPU-" + sys.argv[1]
apspu_id = "APSPU-" + sys.argv[1]
serial = sys.argv[2]
apspu.eeprom.wr_rd_eeprom(id, address=0)
apspu.eeprom.wr_rd_eeprom(serial, address=0x20)
rw_ok = apspu.eeprom.wr_rd_eeprom(apspu_id, address=0)
if rw_ok:
rw_ok = apspu.eeprom.wr_rd_eeprom(serial, address=0x20)
if not rw_ok:
print("EEPROM Error")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment