from builtins import object
__author__ = 'lessju'
import pyfabil.boards.tpm_hw_definitions as tpm_hw_definitions
from pyfabil.plugins.firmwareblock import FirmwareBlock
from pyfabil.base.definitions import *
from pyfabil.base.utils import *
import logging
import time
[docs]
class lasc_reg(object):
adc_mux = 0x00
adc_lRADC = 0x01
adc_hRADC = 0x02
imon_ctrl = 0x03
imon_select = 0x04
imon_avg_l = 0x05
imon_avg_h = 0x06
monitor_select = 0x07
monitor_record = 0x08
output_ctrl_blk = 0x70
tmon_1_h = 0x80
tmon_1_l = 0x81
tmon_2_h = 0x82
tmon_2_l = 0x83
tmon_int_h = 0x84
tmonint_l = 0x85
tmon_stat_a1 = 0x86
tmon_stat_b = 0x87
[docs]
class lasc_inst(object):
READ_ID = 0x2
READ_STATUS = 0x3
WRITE_MEAS_CTRL = 0x51
READ_MEAS_CTRL = 0x52
[docs]
class TpmLasc(FirmwareBlock):
""" FirmwareBlock tests class """
@compatibleboards(BoardMake.TpmBoard)
@friendlyname('tpm_lasc')
@maxinstances(1)
def __init__(self, board, **kwargs):
""" TpmLasc initialiser
:param board: Pointer to board instance
"""
super(TpmLasc, self).__init__(board)
self._board_type = kwargs.get('board_type', 'XTPM')
self.voltage_dict = {
'5V0' : self.get_voltage_5v0,
'FPGA0_CORE' : self.get_voltage_fpga0,
'FPGA1_CORE' : self.get_voltage_fpga1,
'MGT_AV' : self.get_voltage_av,
'MGT_AVTT' : self.get_voltage_avtt,
'SW_AVDD1' : self.get_voltage_avdd1,
'SW_AVDD2' : self.get_voltage_avdd2,
'SW_AVDD3' : self.get_voltage_avdd3,
'VCC_AUX' : self.get_voltage_vcc_aux,
'VIN' : self.get_voltage_vin
}
self.current_dict = {
'ACS_5V0_VI' : self.get_current_5v0
}
self._available_voltages = list(self.voltage_dict.keys())
self._available_currents = list(self.current_dict.keys())
# Enable retry loop if CPLD firmware does not have I2C conflict fix
if self.board["board.regfile.date_code"] < tpm_hw_definitions.CPLD_FW_VER_REQUIRED_FOR_I2C_CMD_ACK_TPM_V1_2:
# Avoid anomalous readings, if measurements > threshold they will be read again
# If the value is still > threshold after nof retries is reached then the most recent value is taken
self.retry_threshold = 50.0 # ( units V or A)
self.max_nof_retries = 5
else:
self.retry_threshold = 50.0 # ( units V or A)
self.max_nof_retries = 0
#######################################################################################
[docs]
def lasc_write(self, is_code, data):
i2c_data = ((is_code & 0xFF) << 8) + (data & 0xFF)
self.board.tpm_i2c.write(i2c_add=0xC0,
nof_wr_byte=3,
nof_rd_byte=0,
wr_data=i2c_data)
[docs]
def lasc_write_mctrl(self, is_code, regadd, data):
i2c_data = ((data & 0xFF) << 16) + ((regadd & 0xFF) << 8) + (is_code & 0xFF)
self.board.tpm_i2c.write(i2c_add=0xC0,
nof_wr_byte=4,
nof_rd_byte=0,
wr_data=i2c_data)
[docs]
def lasc_read(self, is_code, rnbyte):
i2c_data = is_code & 0xFF
return self.board.tpm_i2c.read(i2c_add=0xC0,
nof_wr_byte=1,
nof_rd_byte=rnbyte,
wr_data=i2c_data)
[docs]
def lasc_read_mctrl(self, is_code, regadd, rnbyte):
i2c_data = ((regadd & 0xFF) << 8) + (is_code & 0xff)
return self.board.tpm_i2c.read(i2c_add=0xC0,
nof_wr_byte=2,
nof_rd_byte=rnbyte,
wr_data=i2c_data)
[docs]
def read_id(self):
id = self.lasc_read(lasc_inst.READ_ID, 1)
return id
[docs]
def read_vmon1(self):
self.lasc_write_mctrl(lasc_inst.WRITE_MEAS_CTRL, lasc_reg.adc_mux, 0x80)
time.sleep(0.02)
vmon1_l = self.lasc_read_mctrl(lasc_inst.READ_MEAS_CTRL, lasc_reg.adc_lRADC, 0x1)
vmon1_h = self.lasc_read_mctrl(lasc_inst.READ_MEAS_CTRL, lasc_reg.adc_hRADC, 0x1)
vmon1_value = (vmon1_h << 5)+((vmon1_l & 0xF8) >> 3)
return vmon1_value*2
[docs]
def read_vmon2to7(self,mon_id):
if mon_id < 2 or mon_id > 7:
logging.error("TpmLasc: Invalid id channel")
return -1
self.lasc_write_mctrl(lasc_inst.WRITE_MEAS_CTRL, lasc_reg.adc_mux, (0x0+(mon_id-1)))
time.sleep(0.02)
vmon2_7_l = self.lasc_read_mctrl(lasc_inst.READ_MEAS_CTRL, lasc_reg.adc_lRADC, 0x1)
vmon2_7_h = self.lasc_read_mctrl(lasc_inst.READ_MEAS_CTRL, lasc_reg.adc_hRADC, 0x1)
vmon2_7_value = (vmon2_7_h << 5)+((vmon2_7_l & 0xF8) >> 3)
return vmon2_7_value*2
[docs]
def read_vmon8(self):
self.lasc_write_mctrl(lasc_inst.WRITE_MEAS_CTRL, lasc_reg.adc_mux, (0x87))
time.sleep(0.02)
vmon8_l=self.lasc_read_mctrl(lasc_inst.READ_MEAS_CTRL, lasc_reg.adc_lRADC, 0x1)
vmon8_h=self.lasc_read_mctrl(lasc_inst.READ_MEAS_CTRL, lasc_reg.adc_hRADC, 0x1)
vmon8_value = (vmon8_h << 5)+((vmon8_l & 0xF8) >> 3)
return vmon8_value*2
[docs]
def read_vmon9(self):
self.lasc_write_mctrl(lasc_inst.WRITE_MEAS_CTRL, lasc_reg.adc_mux, (0x88))
time.sleep(0.02)
vmon9_l=self.lasc_read_mctrl(lasc_inst.READ_MEAS_CTRL, lasc_reg.adc_lRADC, 0x1)
vmon9_h=self.lasc_read_mctrl(lasc_inst.READ_MEAS_CTRL, lasc_reg.adc_hRADC, 0x1)
vmon9_value=(vmon9_h << 5)+((vmon9_l & 0xF8) >> 3)
return vmon9_value*2
[docs]
def read_hvmon(self):
self.lasc_write_mctrl(lasc_inst.WRITE_MEAS_CTRL, lasc_reg.adc_mux, (0x89))
time.sleep(0.02)
hvmon_l = self.lasc_read_mctrl(lasc_inst.READ_MEAS_CTRL, lasc_reg.adc_lRADC, 0x1)
hvmon_h = self.lasc_read_mctrl(lasc_inst.READ_MEAS_CTRL, lasc_reg.adc_hRADC, 0x1)
hvmon_value=(hvmon_h << 5)+((hvmon_l & 0xF8) >> 3)
return hvmon_value*2
[docs]
def read_himon(self):
self.lasc_write_mctrl(lasc_inst.WRITE_MEAS_CTRL, lasc_reg.adc_mux, (0x13))
time.sleep(0.02)
hvmon_l=self.lasc_read_mctrl(lasc_inst.READ_MEAS_CTRL, lasc_reg.adc_lRADC, 0x1)
hvmon_h=self.lasc_read_mctrl(lasc_inst.READ_MEAS_CTRL, lasc_reg.adc_hRADC, 0x1)
hvmon_value=(hvmon_h<<5)+((hvmon_l&0xF8)>>3)
return hvmon_value*2
[docs]
def read_imon(self):
self.lasc_write_mctrl(lasc_inst.WRITE_MEAS_CTRL, lasc_reg.adc_mux, (0x80))
time.sleep(0.02)
hvmon_l=self.lasc_read_mctrl(lasc_inst.READ_MEAS_CTRL, lasc_reg.adc_lRADC, 0x1)
hvmon_h=self.lasc_read_mctrl(lasc_inst.READ_MEAS_CTRL, lasc_reg.adc_hRADC, 0x1)
hvmon_value=(hvmon_h<<5)+((hvmon_l&0xF8)>>3)
return hvmon_value*2
[docs]
def get_voltage_5v0(self):
return round(self.read_vmon1() * 0.001, 2)
[docs]
def get_voltage_fpga0(self):
return round(self.read_vmon2to7(2) * 0.001, 2)
[docs]
def get_voltage_fpga1(self):
return round(self.read_vmon2to7(3) * 0.001, 2)
[docs]
def get_voltage_av(self):
return round(self.read_vmon2to7(4) * 0.001, 2)
[docs]
def get_voltage_avtt(self):
return round(self.read_vmon2to7(5) * 0.001, 2)
[docs]
def get_voltage_vcc_aux(self):
return round(self.read_vmon2to7(6) * 0.001, 2)
[docs]
def get_voltage_avdd1(self):
return round(self.read_vmon2to7(7) * 0.001, 2)
[docs]
def get_voltage_avdd2(self):
return round(self.read_vmon8() * 0.001, 2)
[docs]
def get_voltage_avdd3(self):
return round(self.read_vmon9() * 0.001, 2)
[docs]
def get_voltage_vin(self):
# TODO add support here for VIN_SCALED
# IF JP1 and JP2 open
# VIN = VIN_SCALED / (10/(3.16+10))
# IF JP1 closed
# VIN = VIN_SCALED / ((13/30)/(3.16+(13/30)))
# IF JP1 and JP2 closed
# VIN = VIN_SCALED / ((23/30)/(3.16+(23/30)))
# return VIN
return None
[docs]
def get_current_5v0(self):
return None
# TODO: add support here for ACS_5V0_VI
[docs]
def get_voltage(self, voltage=None):
if voltage is None:
voltages = self._available_voltages
else:
if voltage not in self._available_voltages:
# raise PluginError(f"No voltage named '{voltage}' \n Options are {', '.join(self._available_voltages)}")
return {}
voltages = [voltage]
rt = {}
for v in voltages:
measurement = self.voltage_dict[v]()
if measurement is None:
rt[v] = None
continue
count = 0
while count < self.max_nof_retries and measurement > self.retry_threshold:
measurement = self.voltage_dict[v]()
count += 1
rt[v] = measurement
return rt
[docs]
def get_current(self, current=None):
if current is None:
currents = self._available_currents
else:
if current not in self._available_currents:
# raise PluginError(f"No current named '{current}' \n Options are {', '.join(self._available_currents)}")
return {}
currents = [current]
rt = {}
for c in currents:
measurement = self.current_dict[c]()
if measurement is None:
rt[c] = None
continue
count = 0
while count < self.max_nof_retries and measurement > self.retry_threshold:
measurement = self.current_dict[c]()
count += 1
rt[c] = measurement
return rt
[docs]
def get_available_voltages(self):
return self._available_voltages
[docs]
def get_available_currents(self):
return self._available_currents
##################### Superclass method implementations #################################
[docs]
def initialise(self):
""" Initialise TpmLasc """
logging.info("TpmLasc has been initialised")
return True
[docs]
def status_check(self):
""" Perform status check
:return: Status
"""
logging.info("TpmLasc : Checking status")
return Status.OK
[docs]
def clean_up(self):
""" Perform cleanup
:return: Success
"""
logging.info("TpmLasc : Cleaning up")
return True