Source code for pyfabil.plugins.tpm.sysmon

from __future__ import division
from builtins import str
__author__ = 'chiello'

from pyfabil.plugins.firmwareblock import FirmwareBlock
from pyfabil.base.definitions import *
from pyfabil.base.utils import *
import logging
import time

ad_fpga = [
    {"name": "VM_FE0",       "ref": 3.5000, "fpga": 0, "ch": 6,  "divider": 11.5/(31.6+11.5)},
    {"name": "VM_FE1",       "ref": 3.5000, "fpga": 1, "ch": 8,  "divider": 11.5/(31.6+11.5)},
    {"name": "ACS_FE0_VI",   "ref": 3.5000, "fpga": 0, "ch": 5,  "divider": 0.0450, "unit": "A"},
    {"name": "ACS_FE1_VI",   "ref": 3.5000, "fpga": 1, "ch": 14, "divider": 0.0450, "unit": "A"},
    {"name": "VM_DDR0_VTT",  "ref": 0.6750, "fpga": 0, "ch": 9},
    {"name": "VM_DDR0_VREF", "ref": 0.6750, "fpga": 0, "ch": 14},
    {"name": "VM_AGP0",      "ref": 0.9850, "fpga": 0, "ch": 0},
    {"name": "VM_AGP1",      "ref": 0.9850, "fpga": 0, "ch": 1},
    {"name": "VM_AGP2",      "ref": 0.9850, "fpga": 0, "ch": 2},
    {"name": "VM_AGP3",      "ref": 0.9850, "fpga": 0, "ch": 3},
    {"name": "VM_AGP4",      "ref": 0.9850, "fpga": 1, "ch": 0},
    {"name": "VM_AGP5",      "ref": 0.9850, "fpga": 1, "ch": 1},
    {"name": "VM_AGP6",      "ref": 0.9850, "fpga": 1, "ch": 2},
    {"name": "VM_AGP7",      "ref": 0.9850, "fpga": 1, "ch": 3},
    {"name": "VM_CLK0B",     "ref": 3.3000, "fpga": 0, "ch": 8,  "divider": 11.5/(31.6+11.5)},
    {"name": "VM_CLK1B",     "ref": 3.3000, "fpga": 1, "ch": 7,  "divider": 11.5/(31.6+11.5)},
    {"name": "VM_MGT0_AUX",  "ref": 1.8000, "fpga": 0, "ch": 15, "divider": 11.5/(20+11.5)},
    {"name": "VM_MGT1_AUX",  "ref": 1.8000, "fpga": 1, "ch": 11, "divider": 11.5/(20+11.5)},
    {"name": "VM_ADA0",      "ref": 3.3000, "fpga": 0, "ch": 13, "divider": 11.5/(31.6+11.5)},
    {"name": "VM_ADA1",      "ref": 3.3000, "fpga": 0, "ch": 12, "divider": 11.5/(31.6+11.5)},
    {"name": "VM_ADA2",      "ref": 3.3000, "fpga": 1, "ch": 4,  "divider": 11.5/(31.6+11.5)},
    {"name": "VM_ADA3",      "ref": 3.3000, "fpga": 1, "ch": 5,  "divider": 11.5/(31.6+11.5)},
    {"name": "VM_PLL",       "ref": 3.3000, "fpga": 0, "ch": 7,  "divider": 11.5/(31.6+11.5)},
    {"name": "VM_MAN1V2",    "ref": 1.2000, "fpga": 0, "ch": 11, "divider": 10.2/(4.99+10.2)},
    {"name": "VM_MAN2V5",    "ref": 2.5000, "fpga": 0, "ch": 10, "divider": 11.5/(20+11.5)},
    {"name": "VM_MAN3V3",    "ref": 3.3000, "fpga": 0, "ch": 4,  "divider": 11.5/(31.6+11.5)},
    {"name": "VM_DDR1_VTT",  "ref": 0.6750, "fpga": 1, "ch": 12},
    {"name": "VM_DDR1_VREF", "ref": 0.6750, "fpga": 1, "ch": 13},
    {"name": "VM_DDR_VDD",   "ref": 1.3500, "fpga": 1, "ch": 9,  "divider": 10.2/(4.99+10.2)},
    {"name": "VM_SW_DVDD",   "ref": 1.6500, "fpga": 1, "ch": 6,  "divider": 20/(15+20)},
    {"name": "VM_SW_AMP",    "ref": 3.5000, "fpga": 1, "ch": 15, "divider": 11.5/(31.6+11.5)},
    ]
    # ACS_FE0_VI & ACS_FE1_VI known defective 
    # VM_MAN1V2 & VM_SW_AMP will not be as expected as not turned on
    # ADAs default to disabled so VM_ADA0, VM_ADA1, VM_ADA2 & VM_ADA3 will be approx 0 in this configuration
    # Other readings should be as expected ("ref" measurement)

[docs] def get_value_index(name, device): if device == "fpga1": fpga_ind = 0 else: fpga_ind = 1 for i in range(0, len(ad_fpga)): if (name == ad_fpga[i]["name"]) and (fpga_ind == ad_fpga[i]["fpga"]): return i return -1
[docs] class TpmSysmon(FirmwareBlock): """ FirmwareBlock tests class """ @compatibleboards(BoardMake.TpmBoard, BoardMake.Tpm16Board) @friendlyname('tpm_sysmon') @maxinstances(2) def __init__(self, board, **kwargs): """ TpmSysmon initialiser :param board: Pointer to board instance """ super(TpmSysmon, self).__init__(board) self._board_type = kwargs.get('board_type', 'XTPM') if 'device' not in list(kwargs.keys()): raise PluginError("TpmFpga: Require a node instance") self._device = kwargs['device'] if self._device == Device.FPGA_1: self._device = 'fpga1' elif self._device == Device.FPGA_2: self._device = 'fpga2' else: raise PluginError("TpmFpga: Invalid device %s" % self._device)
[docs] def initialize(self): """ Reset System Monitor """ self.board['%s.sys_mon.sysmonrr' % self._device] = 0x1 self.board['%s.sys_mon.sysmonrr' % self._device] = 0x0
[docs] def get_fpga_temperature(self): """ Read FPGA temperature""" rdval = self.board['%s.sys_mon.temp' % self._device] temp = ((rdval * 501.3743) / 65536) - 273.67777 return temp
[docs] def read_adx(self, ad_idx): """ Read specified AD to get VAUX""" if int(ad_idx) > 15 or int(ad_idx) < 0: logging.error('%s sysmon, invalid AD index %s' % (self._device, str(ad_idx))) return -1 else: rdval = self.board['%s.sys_mon.vaux_%s' % (self._device, str(ad_idx))] voltage = float(rdval) * 1/65536 return voltage
[docs] def read_conf_regs(self): """ Read consifguration registers""" rdval0 = self.board['%s.sys_mon.conf_reg_0' % self._device] rdval1 = self.board['%s.sys_mon.conf_reg_1' % self._device] rdval2 = self.board['%s.sys_mon.conf_reg_2' % self._device] rdval3 = self.board['%s.sys_mon.conf_reg_3' % self._device] return rdval0, rdval1, rdval2, rdval3
[docs] def get_vcc_int(self): """ Read internal VCC""" val = self.board['%s.sys_mon.vccint' % self._device] val = float(val)/65536*3 return val
[docs] def get_vcc_aux(self): """ Read internal VAUX""" val = self.board['%s.sys_mon.vccaux' % self._device] val = float(val)/65536*3 return val
[docs] def get_vcc_fe(self): expected = 0.934 nominal = 3.5 if self._device == "fpga1": vcc = self.read_adx(6) else: vcc = self.read_adx(8) vcc = vcc / expected * nominal return vcc
[docs] def get_available_voltages(self): voltages = [] if self._device == "fpga1": fpga_ind = 0 else: fpga_ind = 1 for i in range(0, len(ad_fpga)): if fpga_ind == ad_fpga[i]["fpga"] and ad_fpga[i].get("unit") != "A": voltages.append(ad_fpga[i]["name"]) return voltages
[docs] def get_available_currents(self): currents = [] if self._device == "fpga1": fpga_ind = 0 else: fpga_ind = 1 for i in range(0, len(ad_fpga)): if fpga_ind == ad_fpga[i]["fpga"] and ad_fpga[i].get("unit") == "A": currents.append(ad_fpga[i]["name"]) return currents
[docs] def get_measure_val(self, name): index = get_value_index(name,self._device) if index == -1: logging.error("ERROR: measure not available check provided name") return -1 else: val = self.read_adx(ad_fpga[index]["ch"]) if "divider" in ad_fpga[index]: val = val / ad_fpga[index]["divider"] return val
[docs] def get_voltage(self, voltage=None): if voltage is None: voltages = self.get_available_voltages() else: if voltage not in self.get_available_voltages(): # raise PluginError(f"No voltage named '{voltage}' \n Options are {', '.join(self.get_available_voltages())}") return {} voltages = [voltage] rt = {} for name in voltages: rt[name] = round(self.get_measure_val(name), 2) return rt
[docs] def get_current(self, current=None): if current is None: currents = self.get_available_currents() else: if current not in self.get_available_currents(): # raise PluginError(f"No current named '{current}' \n Options are {', '.join(self.get_available_currents())}") return {} currents = [current] rt = {} for name in currents: rt[name] = round(self.get_measure_val(name), 2) return rt
##################### Superclass method implementations #################################
[docs] def initialise(self): """ Initialise TpmSysmon """ logging.info("TpmSysmon has been initialised") return True
[docs] def status_check(self): """ Perform status check :return: Status """ logging.info("TpmSysmon : Checking status") return Status.OK
[docs] def clean_up(self): """ Perform cleanup :return: Success """ logging.info("TpmSysmon : Cleaning up") return True