Source code for ska_low_sps_tpm_api.plugins.mcu

import ska_low_sps_tpm_api.boards.tpm_hw_definitions as tpm_hw_definitions
from ska_low_sps_tpm_api.base.definitions import *
from ska_low_sps_tpm_api.base.utils import *
from ska_low_sps_tpm_api.plugins.firmwareblock import FirmwareBlock

__author__ = "Gabriele Sorrenti"

FRAM_BA = 0x90000000  # MCU shadow RAM offset


[docs] class McuRegisters(object): FRAM_MCU_VERSION = 0x00000000 FRAM_MCU_COMPILE_DATE = 0x00000004 FRAM_MCU_GIT_HASH = 0x00000008 FRAM_MCU_GPR_0 = 0x0000000C FRAM_MCU_GPR_1 = 0x00000010 FRAM_MCU_GPR_2 = 0x00000014 FRAM_MCU_GPR_3 = 0x00000018 FRAM_MCU_POOLING_INTERVAL = 0x0000001C FRAM_MCU_INTERNAL_COMMAND = 0x00000020 FRAM_MCU_COUNTER = 0x00000024 FRAM_MCU_COMPLETE_ADC_COUNTER = 0x00000028 FRAM_MCU_BOOTLOADER_VERSION = 0x0000002C FRAM_MCU_BOOTLOADER_COMMANDS = 0x00000030 FRAM_MCU_STEP = 0x000000038 FRAM_MCU_UART_DBG_DIS = 0x00000040 FRAM_MCU_FEATURES = 0x00000044 FRAM_BOARD_STATUS = 0x000000E0 FRAM_BOARD_ALARM = 0x000000E4 FRAM_BOARD_WARNING = 0x000000E8 FRAM_ALM_ERR_VALUE = 0x000000EC FRAM_WARN_ERR_VALUE = 0x000000F0 FRAM_I2C_UNREACH_ERR = 0x000000F4 FRAM_POWERGOOD_ERR = 0x000000FA FRAM_POWERGOOD = 0x000000FC FRAM_ADC_SW_AVDD1 = 0x00000100 FRAM_ADC_SW_AVDD2 = 0x00000104 FRAM_ADC_AVDD3 = 0x00000108 FRAM_ADC_MAN_1V2 = 0x0000010C FRAM_ADC_DDR0_VREF = 0x00000110 FRAM_ADC_DDR1_VREF = 0x00000114 FRAM_ADC_VM_DRVDD = 0x00000118 FRAM_ADC_VIN_SCALED = 0x0000011C FRAM_ADC_VM_MAN3V3 = 0x00000120 FRAM_ADC_VM_MAN1V8 = 0x00000124 FRAM_ADC_MON_5V0 = 0x00000128 FRAM_ADC_MGT_AV = 0x0000012C FRAM_ADC_MGT_AVTT = 0x00000130 FRAM_ADC_INTERNAL_MCU_TEMP = 0x00000134 FRAM_BOARD_TEMP = 0x00000138 FRAM_FPGA0_TEMP = 0x0000013C FRAM_FPGA1_TEMP = 0x00000140 FRAM_FPGA0_FE_CURRENT = 0x00000144 FRAM_FPGA1_FE_CURRENT = 0x00000148 FRAM_WARN_ALARM_UPDATE = 0x00000190 FRAM_WARN_THR_SW_AVDD1 = 0x00000194 FRAM_WARN_THR_SW_AVDD2 = 0x00000198 FRAM_WARN_THR_AVDD3 = 0x0000019C FRAM_WARN_THR_MAN_1V2 = 0x000001A0 FRAM_WARN_THR_DDR0_VREF = 0x000001A4 FRAM_WARN_THR_DDR1_VREF = 0x000001A8 FRAM_WARN_THR_VM_DRVDD = 0x000001AC FRAM_WARN_THR_VIN_SCALED = 0x000001B0 FRAM_WARN_THR_VM_MAN3V3 = 0x000001B4 FRAM_WARN_THR_VM_MAN1V8 = 0x000001B8 FRAM_WARN_THR_MON_5V0 = 0x000001BC FRAM_WARN_THR_MGT_AV = 0x000001C0 FRAM_WARN_THR_MGT_AVTT = 0x000001C4 FRAM_WARN_THR_INTERNAL_MCU_TEMP = 0x000001C8 FRAM_WARN_THR_BOARD_TEMP = 0x000001CC FRAM_WARN_THR_FPGA0_TEMP = 0x000001D0 FRAM_WARN_THR_FPGA1_TEMP = 0x000001D4 FRAM_WARN_THR_FPGA0_FE_CURRENT = 0x000001D8 FRAM_WARN_THR_FPGA1_FE_CURRENT = 0x000001E0 FRAM_ALARM_THR_SW_AVDD1 = 0x00000220 FRAM_ALARM_THR_SW_AVDD2 = 0x00000224 FRAM_ALARM_THR_AVDD3 = 0x00000228 FRAM_ALARM_THR_MAN_1V2 = 0x0000022C FRAM_ALARM_THR_DDR0_VREF = 0x00000230 FRAM_ALARM_THR_DDR1_VREF = 0x00000234 FRAM_ALARM_THR_VM_DRVDD = 0x00000238 FRAM_ALARM_THR_VIN_SCALED = 0x0000023C FRAM_ALARM_THR_VM_MAN3V3 = 0x00000240 FRAM_ALARM_THR_VM_MAN1V8 = 0x00000244 FRAM_ALARM_THR_MON_5V0 = 0x00000248 FRAM_ALARM_THR_MGT_AV = 0x0000024C FRAM_ALARM_THR_MGT_AVTT = 0x00000250 FRAM_ALARM_THR_INTERNAL_MCU_TEMP = 0x00000254 FRAM_ALARM_THR_BOARD_TEMP = 0x00000258 FRAM_ALARM_THR_FPGA0_TEMP = 0x0000025C FRAM_ALARM_THR_FPGA1_TEMP = 0x00000260 FRAM_ALARM_THR_FPGA0_FE_CURRENT = 0x00000264 FRAM_ALARM_THR_FPGA1_FE_CURRENT = 0x00000268 MCU_ADC_OFFSET = FRAM_ADC_SW_AVDD1 ALARM_THR_OFFSET = FRAM_ALARM_THR_SW_AVDD1 TEMPS_OFFSET = FRAM_BOARD_TEMP
Mcu_Feature = { "FIX_FEx_mAV_READ": 0x1, } McuADCs = { "ADC_SW_AVDD1": {"add": McuRegisters.FRAM_ADC_SW_AVDD1, "status": 1, "divider": 0}, "ADC_SW_AVDD2": {"add": McuRegisters.FRAM_ADC_SW_AVDD2, "status": 2, "divider": 0}, "ADC_AVDD3": {"add": McuRegisters.FRAM_ADC_AVDD3, "status": 4, "divider": 0}, "ADC_MAN_1V2": {"add": McuRegisters.FRAM_ADC_MAN_1V2, "status": 8, "divider": 0}, "ADC_DDR0_VREF": { "add": McuRegisters.FRAM_ADC_DDR0_VREF, "status": 16, "divider": 0, }, "ADC_DDR1_VREF": { "add": McuRegisters.FRAM_ADC_DDR1_VREF, "status": 32, "divider": 0, }, "ADC_VM_DRVDD": {"add": McuRegisters.FRAM_ADC_VM_DRVDD, "status": 64, "divider": 0}, "ADC_VIN_SCALED": { "add": McuRegisters.FRAM_ADC_VIN_SCALED, "status": 128, "divider": 12.5, }, "ADC_VM_MAN3V3": { "add": McuRegisters.FRAM_ADC_VM_MAN3V3, "status": 256, "divider": 3.74782, }, "ADC_VM_MAN1V8": { "add": McuRegisters.FRAM_ADC_VM_MAN1V8, "status": 512, "divider": 2.73914, }, "ADC_MON_5V0": { "add": McuRegisters.FRAM_ADC_MON_5V0, "status": 1024, "divider": 2.739276, }, "ADC_MGT_AV": {"add": McuRegisters.FRAM_ADC_MGT_AV, "status": 2048, "divider": 0}, "ADC_MGT_AVTT": { "add": McuRegisters.FRAM_ADC_MGT_AVTT, "status": 4096, "divider": 0, }, "FE0_mVA": { "add": McuRegisters.FRAM_FPGA0_FE_CURRENT, "status": 4096, "divider": 0, }, "FE1_mVA": { "add": McuRegisters.FRAM_FPGA1_FE_CURRENT, "status": 4096, "divider": 0, }, } Warn_Thresholds = { "ADC_SW_AVDD1": {"add": McuRegisters.FRAM_WARN_THR_SW_AVDD1, "divider": 0}, "ADC_SW_AVDD2": {"add": McuRegisters.FRAM_WARN_THR_SW_AVDD2, "divider": 0}, "ADC_AVDD3": {"add": McuRegisters.FRAM_WARN_THR_AVDD3, "divider": 0}, "ADC_MAN_1V2": {"add": McuRegisters.FRAM_WARN_THR_MAN_1V2, "divider": 0}, "ADC_DDR0_VREF": {"add": McuRegisters.FRAM_WARN_THR_DDR0_VREF, "divider": 0}, "ADC_DDR1_VREF": {"add": McuRegisters.FRAM_WARN_THR_DDR1_VREF, "divider": 0}, "ADC_VM_DRVDD": {"add": McuRegisters.FRAM_WARN_THR_VM_DRVDD, "divider": 0}, "ADC_VIN_SCALED": {"add": McuRegisters.FRAM_WARN_THR_VIN_SCALED, "divider": 12.5}, "ADC_VM_MAN3V3": {"add": McuRegisters.FRAM_WARN_THR_VM_MAN3V3, "divider": 3.74782}, "ADC_VM_MAN1V8": {"add": McuRegisters.FRAM_WARN_THR_VM_MAN1V8, "divider": 2.73914}, "ADC_MON_5V0": {"add": McuRegisters.FRAM_WARN_THR_MON_5V0, "divider": 2.739276}, "ADC_MGT_AV": {"add": McuRegisters.FRAM_WARN_THR_MGT_AV, "divider": 0}, "ADC_MGT_AVTT": {"add": McuRegisters.FRAM_WARN_THR_MGT_AVTT, "divider": 0}, "FE0_mVA": {"add": McuRegisters.FRAM_WARN_THR_FPGA0_FE_CURRENT, "divider": 0}, "FE1_mVA": {"add": McuRegisters.FRAM_WARN_THR_FPGA1_FE_CURRENT, "divider": 0}, } Alarm_Thresholds = { "ADC_SW_AVDD1": {"add": McuRegisters.FRAM_ALARM_THR_SW_AVDD1, "divider": 0}, "ADC_SW_AVDD2": {"add": McuRegisters.FRAM_ALARM_THR_SW_AVDD2, "divider": 0}, "ADC_AVDD3": {"add": McuRegisters.FRAM_ALARM_THR_AVDD3, "divider": 0}, "ADC_MAN_1V2": {"add": McuRegisters.FRAM_ALARM_THR_MAN_1V2, "divider": 0}, "ADC_DDR0_VREF": {"add": McuRegisters.FRAM_ALARM_THR_DDR0_VREF, "divider": 0}, "ADC_DDR1_VREF": {"add": McuRegisters.FRAM_ALARM_THR_DDR1_VREF, "divider": 0}, "ADC_VM_DRVDD": {"add": McuRegisters.FRAM_ALARM_THR_VM_DRVDD, "divider": 0}, "ADC_VIN_SCALED": {"add": McuRegisters.FRAM_ALARM_THR_VIN_SCALED, "divider": 12.5}, "ADC_VM_MAN3V3": {"add": McuRegisters.FRAM_ALARM_THR_VM_MAN3V3, "divider": 3.74782}, "ADC_VM_MAN1V8": {"add": McuRegisters.FRAM_ALARM_THR_VM_MAN1V8, "divider": 2.73914}, "ADC_MON_5V0": {"add": McuRegisters.FRAM_ALARM_THR_MON_5V0, "divider": 2.739276}, "ADC_MGT_AV": {"add": McuRegisters.FRAM_ALARM_THR_MGT_AV, "divider": 0}, "ADC_MGT_AVTT": {"add": McuRegisters.FRAM_ALARM_THR_MGT_AVTT, "divider": 0}, "FE0_mVA": {"add": McuRegisters.FRAM_ALARM_THR_FPGA0_FE_CURRENT, "divider": 0}, "FE1_mVA": {"add": McuRegisters.FRAM_ALARM_THR_FPGA1_FE_CURRENT, "divider": 0}, } VoltTemps = [ "SW_AVDD1", "SW_AVDD2", "AVDD3", "MAN_1V2", "DDR0_VREF", "DDR1_VREF", "VM_DRVDD", "VIN", "MON_3V3", "MON_1V8", "MON_5V0", "MGT_AVCC", "MGT_AVTT", "TEMP_MCU", "TEMP_BOARD", "TEMP_FPGA0", "TEMP_FPGA1", "FE0_mVA", "FE1_mVA", ] mcu_exec_steps_t = [ "null", "post_internal_periph_init", "pre_startup_stuff", "startup_stuff", "eth_reg_init", "checkpowergood", "systemmonitorstart", "startuploadsettings", "post_startup_stuff", "pre_main_loop", "i2c_manage", "adcreadsingle", "alarmmanage", "irqinternalcpldhandler", "taskslow", "irqinternalpghandler", "twidatablock", "exchangedatablock", "exchangedatablockxilinx", "smaplock", "smapunlock", "exchangedatablockxilinx2", "exchangedatablockxilinx3", "exchangedatablockxilinx4", "exchangedatablockxilinx5", "exchangedatablockxilinx6", "taskslow1", "taskslow2", "taskslow3", "exchangedatablockxilinx7", "exchangedatablockxilinx8", "exchangedatablockxilinx9", "exchangedatablockxilinx10", "xilaccessdbg", "smaplockrenew", "smaplock_1", "i2c_manage_req", "i2c_manage_deasserve", "i2c_manage_check", "i2c_manage_end", "i2c_manage_rlow", "check_bus", ]
[docs] class TpmMcu(FirmwareBlock): """TpmMcu plugin"""
[docs] @compatibleboards(BoardMake.TpmBoard) @friendlyname("tpm_monitor") @maxinstances(1) def __init__(self, board, logger=None, **kwargs): """ TpmMcu initialiser. :param board: Pointer to board instance """ super(TpmMcu, self).__init__(board, logger=logger) self._board_type = kwargs.get("board_type", "XTPM") self.voltage_dict_map = { "MGT_AVCC": "ADC_MGT_AV", "MGT_AVTT": "ADC_MGT_AVTT", "SW_AVDD1": "ADC_SW_AVDD1", "SW_AVDD2": "ADC_SW_AVDD2", "AVDD3": "ADC_AVDD3", "MAN_1V2": "ADC_MAN_1V2", "DDR0_VREF": "ADC_DDR0_VREF", "DDR1_VREF": "ADC_DDR1_VREF", "VM_DRVDD": "ADC_VM_DRVDD", "VIN": "ADC_VIN_SCALED", "MON_3V3": "ADC_VM_MAN3V3", "MON_1V8": "ADC_VM_MAN1V8", "MON_5V0": "ADC_MON_5V0", } self.current_dict_map = {} self.FRAM_MCU_FEATURES = self.board.read_address( FRAM_BA + McuRegisters.FRAM_MCU_FEATURES ) if Mcu_Feature["FIX_FEx_mAV_READ"] & self.FRAM_MCU_FEATURES != 0: self.current_dict_map["FE0_mVA"] = "FE0_mVA" self.current_dict_map["FE1_mVA"] = "FE1_mVA" self._available_voltages = list(self.voltage_dict_map.keys()) self._available_currents = list(self.current_dict_map.keys()) self.set_voltage_warning_thresholds("VIN", 11.4, 12.6) self.logger.info("Disable MCU UART debug output") self.disable_uart_debug_output()
#######################################################################################
[docs] def disable_uart_debug_output(self): """Disable debug trasmission on uart, default at poweron is enabled.""" self.board.write_address((FRAM_BA + McuRegisters.FRAM_MCU_UART_DBG_DIS), 0x1)
[docs] def enable_uart_debug_output(self): """Enable debug trasmission on uart, default at poweron is enabled.""" self.board.write_address((FRAM_BA + McuRegisters.FRAM_MCU_UART_DBG_DIS), 0x0)
[docs] def get_version(self): """ Get MCU FW Version. :return: MCU FW Version (FW Version_Compile_date_InternalCommand) """ version = ( hex(self.board.read_address(FRAM_BA + McuRegisters.FRAM_MCU_VERSION)) + "_" ) version += ( hex(self.board.read_address(FRAM_BA + McuRegisters.FRAM_MCU_COMPILE_DATE)) + "_" ) version += hex( self.board.read_address(FRAM_BA + McuRegisters.FRAM_MCU_INTERNAL_COMMAND) ) return version
[docs] def get_available_mcu_adc(self): """ Get List of Supplies Measures Monitored with MCU ADCs, to be used in other methods :return: List of MCU Measures Names available """ mcu_adc_names = [] for measure in McuADCs: mcu_adc_names.append(measure) print(mcu_adc_names) return mcu_adc_names
[docs] def get_adc_value(self, adc_measure=None, all_measure=None): """ Get single adc_measure current value, or all available measure values and thresholds (mandatory set once of parameter). :param adc_measure: use if want get only current value of selected measure :param all_measure: set to True if want all available measure current value and alarm and thresholds values :return: single selected value, or dictionary with all available measure value and thresholds """ if adc_measure is not None: if adc_measure in McuADCs: measures = [adc_measure] else: self.logger.error( "Error: measure not found, please use one in available" ) op_status = -1 value = -1 return value, op_status elif all_measure is not None: measures = McuADCs values = {} op_status = 0 for meas in measures: # print(meas) value = self.board.read_address(FRAM_BA + McuADCs[meas]["add"]) # print(f"get_adc_value {hex(FRAM_BA+McuADCs[meas]['add'])} {value}") w_tr_reg = self.board.read_address(FRAM_BA + Warn_Thresholds[meas]["add"]) min_w_tr = w_tr_reg & 0xFFFF max_w_tr = (w_tr_reg & 0xFFFF0000) >> 16 a_tr_reg = self.board.read_address(FRAM_BA + Alarm_Thresholds[meas]["add"]) min_a_tr = a_tr_reg & 0xFFFF max_a_tr = (a_tr_reg & 0xFFFF0000) >> 16 data = { "value": value / 1000, "unit": "V", "max_alm": max_a_tr, "min_alm": min_a_tr, "max_wrn": max_w_tr, "min_wrn": min_w_tr, } values[meas] = data op_status = 0 # print(values) if adc_measure is not None: return values[adc_measure], op_status return values, op_status
[docs] def set_thresholds_update(self, message=""): """Update thresholds :param message: message to be logged, default """ self.board.write_address((FRAM_BA + McuRegisters.FRAM_WARN_ALARM_UPDATE), 0x1) self.board._poll_reg( (FRAM_BA + McuRegisters.FRAM_WARN_ALARM_UPDATE), 0, f"FRAM_WARN_ALARM_UPDATE ACK NOT Detected on set_thresholds_update {message}", )
[docs] def set_adc_warning_thresholds(self, adc_measure, min_thr, max_thr): """ Set slected MCU ADC measure Warning Max and Min thresholds values. :param adc_measure: name of available measure to be configured :param min_thr: minimun warning threshold value in Volt :param max_thr: maximun warning threshold value in Volt :return: operation status, 0 success, -1 failed :note: this method not work properly with bios < v0.3.0 """ if adc_measure is not None: if adc_measure in McuADCs: thr_warn_reg = ((int(max_thr * 1000) & 0xFFFF) << 16) | ( int(min_thr * 1000) & 0xFFFF ) self.board.write_address( FRAM_BA + Warn_Thresholds[adc_measure]["add"], thr_warn_reg ) self.set_thresholds_update(f"set_adc_warning_thresholds {adc_measure}") op_status = 0 else: self.logger.error( "Error: measure not found, please use one in available" ) op_status = -1 return op_status
[docs] def set_adc_alarm_thresholds(self, adc_measure, min_thr, max_thr): """ Set slected MCU ADC measure Alarrm Max and Min thresholds values. :param adc_measure: name of available measure to be configured :param min_thr: minimun alarm threshold value in Volt :param max_thr: maximun alarm threshold value in Volt :return: operation status, 0 success, -1 failed :note: this method not work properly with bios < v0.3.0 """ if adc_measure is not None: if adc_measure in McuADCs: thr_alm_reg = ((int(max_thr * 1000) & 0xFFFF) << 16) | ( int(min_thr * 1000) & 0xFFFF ) self.board.write_address( FRAM_BA + Alarm_Thresholds[adc_measure]["add"], thr_alm_reg ) self.set_thresholds_update(f"set_adc_alarm_thresholds {adc_measure}") op_status = 0 else: self.logger.error( "Error: measure not found, please use one in available" ) op_status = -1 return op_status
[docs] def get_rounded_adc_value(self, McuADCs_key): value, op_status = self.get_adc_value(adc_measure=McuADCs_key) return round(value["value"], 3)
[docs] def get_temperature(self): """ Get Board temperature measured on PCB temperature sensor. :return: temperature value, if I2C access error is detected a value of -273 will be returned :note: until ADC PS is ON the returned value of temp is 0 :note: this method can not work properly with bios < v0.3.0 """ step = 0.0625 temp = ( self.board.read_address(FRAM_BA + McuRegisters.FRAM_BOARD_TEMP) ) & 0xFFFF temp_status = (temp & 0xC000) >> 12 if temp & 0x1000 == 0x1000: temp = (temp & 0xFFF) - 4096 else: temp = temp & 0xFFF temp_f = temp * step temp_f = round(temp_f, 2) if ( self.board["board.regfile.date_code"] > self.board.MCU_FW_VER_LOCK_I2C_CHANGE ): if temp_status & 0x8 == 0x8: self.logger.error( "Board Temperature not updated for MCU I2C access error" ) # temp_prev = temp_f temp_upd = -273 elif temp_status & 0x4 == 0x4: self.logger.error( "Board Temperature not updated, ADC PS is Off for Temp Error" ) # temp_prev = temp_f temp_upd = -273 else: # temp_prev = None temp_upd = temp_f else: temp_upd = temp_f return temp_upd
[docs] def get_mcu_temperature(self): """ Get MCU temperature. :return:MCU temperature value """ temp = self.board.read_address( FRAM_BA + McuRegisters.FRAM_ADC_INTERNAL_MCU_TEMP ) temp_f = float(temp / 10000) temp_f = round(temp_f, 2) return temp_f
[docs] def set_board_warn_temp_thresholds(self, max_temp): """ Set board Warning temperature Max thresholds values. :param max_temp: maximun temp threshold value in Celsius degree :note: this method can not work properly with bios < v0.3.0 """ tmax = int(max_temp / 0.0625) regval = (tmax & 0xFFFF) << 16 self.board.write_address( (FRAM_BA + McuRegisters.FRAM_WARN_THR_BOARD_TEMP), regval ) self.set_thresholds_update(f"set_board_warn_temp_thresholds {max_temp}")
[docs] def set_board_alm_temp_thresholds(self, max_temp): """ Set board Alarm temperature Max thresholds values. :param max_temp: maximun temp threshold value in Celsius degree :note: this method can not work properly with bios < v0.3.0 """ tmax = int(max_temp / 0.0625) regval = (tmax & 0xFFFF) << 16 self.board.write_address( (FRAM_BA + McuRegisters.FRAM_ALARM_THR_BOARD_TEMP), regval ) self.set_thresholds_update(f"set_board_alm_temp_thresholds {max_temp}")
[docs] def set_fpga_warn_temp_thresholds(self, max_temp, fpga_id): """ Set selected FPGA Warning temperature Max thresholds values. :param max_temp: maximun temp threshold value in Celsius degree :param fpga_id: select which FPGA' temp thresholds will be configured (possible values:0,1) :note: this method can not work properly with bios < v0.3.0 """ max_value = int((max_temp + 273.67777) * 65536 / 501.3743) regval = (max_value & 0xFFFF) << 16 if fpga_id == 0: self.board.write_address( (FRAM_BA + McuRegisters.FRAM_WARN_THR_FPGA0_TEMP), regval ) else: self.board.write_address( (FRAM_BA + McuRegisters.FRAM_WARN_THR_FPGA1_TEMP), regval ) self.set_thresholds_update( f"set_fpga_warn_temp_thresholds {max_temp} {fpga_id}" )
[docs] def set_fpga_alm_temp_thresholds(self, max_temp, fpga_id): """ Set selected FPGA Alarm temperature Max thresholds values. :param max_temp: maximun temp threshold value in Celsius degree :param fpga_id: select which FPGA' temp thresholds will be configured (possible values:0,1) :note: this method can not work properly with bios < v0.3.0 """ max_value = int((max_temp + 273.67777) * 65536 / 501.3743) regval = (max_value & 0xFFFF) << 16 if fpga_id == 0: self.board.write_address( (FRAM_BA + McuRegisters.FRAM_ALARM_THR_FPGA0_TEMP), regval ) else: self.board.write_address( (FRAM_BA + McuRegisters.FRAM_ALARM_THR_FPGA1_TEMP), regval ) self.set_thresholds_update(f"set_fpga_alm_temp_thresholds {max_temp} {fpga_id}")
[docs] def get_fpga_alm_temp_thresholds(self, fpga_id): """ Get selected FPGA Alarm temperature Max thresholds values. :param fpga_id: select which FPGA' temp thresholds will be returned (possible values:0,1) :return: maximum temperature threshold value :note: this method can not work properly with bios < v0.3.0 """ if fpga_id == 0: add = FRAM_BA + McuRegisters.FRAM_ALARM_THR_FPGA0_TEMP else: add = FRAM_BA + McuRegisters.FRAM_ALARM_THR_FPGA1_TEMP fpga0_raw = self.board[add] fpga_max = (fpga0_raw & 0xFFFF0000) >> 16 max_temp = (fpga_max * 501.3743 / 65536) - 273.67777 max_temp = round(max_temp, 2) return max_temp
[docs] def get_fpga_warn_temp_thresholds(self, fpga_id): """ Get selected FPGA Warning temperature Max thresholds values. :param fpga_id: select which FPGA' temp thresholds will be returned(possible values:0,1) :return: maximum temperature threshold value :note: this method can not work properly with bios < v0.3.0 """ if fpga_id == 0: add = FRAM_BA + McuRegisters.FRAM_WARN_THR_FPGA0_TEMP else: add = FRAM_BA + McuRegisters.FRAM_WARN_THR_FPGA1_TEMP fpga0_raw = self.board[add] fpga_max = (fpga0_raw & 0xFFFF0000) >> 16 max_temp = (fpga_max * 501.3743 / 65536) - 273.67777 max_temp = round(max_temp, 2) return max_temp
[docs] def get_board_warn_temp_thresholds(self): """ Get board Warning temperature Max thresholds values :note: this method can not work properly with bios < v0.3.0 """ add = FRAM_BA + McuRegisters.FRAM_WARN_THR_BOARD_TEMP temp_raw = self.board[add] max_temp = ((temp_raw & 0xFFFF0000) >> 16) * 0.0625 max_temp = round(max_temp, 2) return max_temp
[docs] def get_board_alm_temp_thresholds(self): """ Get board Alarm temperature Max thresholds values. :note: this method can not work properly with bios < v0.3.0 """ add = FRAM_BA + McuRegisters.FRAM_ALARM_THR_BOARD_TEMP temp_raw = self.board[add] max_temp = ((temp_raw & 0xFFFF0000) >> 16) * 0.0625 max_temp = round(max_temp, 2) return max_temp
[docs] def get_mcu_last_exec_phase_id(self): """ Get mcu last execution phase id. :return: last execution phase id """ add = FRAM_BA + McuRegisters.FRAM_MCU_STEP exec_phaseid = self.board[add] mcu_counter = self.board[FRAM_BA + McuRegisters.FRAM_MCU_COUNTER] return [mcu_exec_steps_t[exec_phaseid], mcu_counter]
[docs] def get_last_error(self): """ Get status of voltage or temp error detection by MCU, if error is detected the value that has generated the error will be returned. :return: dictionary with measure name as key and value (e.g. {'VIN': 11.2}), None if no errors detected :note: this method not work properly with bios < v0.3.0 """ add = FRAM_BA + McuRegisters.FRAM_BOARD_ALARM error_status = self.board[add] if error_status > 0: error_status = VoltTemps[int(math.log(error_status, 2))] else: error_status = None add = FRAM_BA + McuRegisters.FRAM_ALM_ERR_VALUE error_value = self.board[add] if error_status in ["TEMP_BOARD"]: error_value = error_value * 0.0625 elif error_status in ["TEMP_FPGA0", "TEMP_FPGA1"]: error_value = (error_value * 501.3743 / 65536) - 273.67777 else: error_value = error_value / 1000 return {error_status: round(error_value, 2)}
[docs] def get_last_warning(self): """ Get status of voltage or temp warning detection by MCU, if warning is detected the value that has generated the warning will be returned. :return: dictionary with measure name as key and value (e.g. {'VIN': 11.2}), None if no warnings detected :note: this method not work properly with bios < v0.3.0 """ add = FRAM_BA + McuRegisters.FRAM_BOARD_WARNING warning_status = self.board[add] if warning_status > 0: warning_status = VoltTemps[int(math.log(warning_status, 2))] else: warning_status = None add = FRAM_BA + McuRegisters.FRAM_WARN_ERR_VALUE warning_value = self.board[add] if warning_status in ["TEMP_BOARD"]: warning_value = warning_value * 0.0625 elif warning_status in ["TEMP_FPGA0", "TEMP_FPGA1"]: warning_value = (warning_value * 501.3743 / 65536) - 273.67777 else: warning_value = warning_value / 1000 return {warning_status: round(warning_value, 2)}
[docs] def get_pgood_err(self): """get status of power good error status. :return: power good error value if not 0 an error was detetcted :note: this method not work properly with bios < v0.3.0 """ add = FRAM_BA + McuRegisters.FRAM_POWERGOOD_ERR pgood_err = self.board[add] return pgood_err
[docs] def get_i2c_unreach_err(self): """ Get status of i2c unreachable error status. :return: i2c unreachable error value if not 0 an error was detetcted :note: this method not work properly with bios < v0.3.0 """ add = FRAM_BA + McuRegisters.FRAM_I2C_UNREACH_ERR i2cunreach_err = self.board[add] return i2cunreach_err
[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: rt[v] = self.get_rounded_adc_value(self.voltage_dict_map[v]) return rt
[docs] def get_voltage_warning_thresholds(self, voltage=None): if voltage is not None: if voltage in self._available_voltages: measures = [voltage] else: self.logger.error( "Error: measure not found, please use one in available" ) return None else: measures = self._available_voltages res = {} for measure in measures: adc_measure = self.voltage_dict_map[measure] if adc_measure is not None: thr_warn_reg = self.board.read_address( FRAM_BA + Warn_Thresholds[adc_measure]["add"] ) res[measure] = { "min": ((thr_warn_reg & 0xFFFF)) / 1000, "max": ((thr_warn_reg & 0xFFFF0000) >> 16) / 1000, } if voltage is not None: return res[voltage] return res
[docs] def set_voltage_warning_thresholds(self, voltage, min_thr, max_thr): if voltage not in self._available_voltages: self.logger.error("Error: measure not found, please use one in available") return None adc_measure = self.voltage_dict_map[voltage] if adc_measure is not None: thr_warn_reg = ((int(max_thr * 1000) & 0xFFFF) << 16) | ( int(min_thr * 1000) & 0xFFFF ) self.board.write_address( FRAM_BA + Warn_Thresholds[adc_measure]["add"], thr_warn_reg ) self.set_thresholds_update( f"set_voltage_warning_thresholds {voltage} {min_thr} {max_thr}" ) return True
[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: rt[c] = self.get_rounded_adc_value(self.current_dict_map[c]) return rt
[docs] def get_current_warning_thresholds(self, current=None): if current is not None: if current in self._available_currents: measures = [current] else: self.logger.error( "Error: measure not found, please use one in available" ) return None else: measures = self._available_currents res = {} for measure in measures: adc_measure = self.current_dict_map[measure] if adc_measure is not None: thr_warn_reg = self.board.read_address( FRAM_BA + Warn_Thresholds[adc_measure]["add"] ) res[measure] = { "min": ((thr_warn_reg & 0xFFFF)) / 1000, "max": ((thr_warn_reg & 0xFFFF0000) >> 16) / 1000, } if current is not None: return res[current] return res
[docs] def set_current_warning_thresholds(self, current, min_thr, max_thr): if current not in self._available_currents: self.logger.error("Error: measure not found, please use one in available") return None adc_measure = self.current_dict_map[current] if adc_measure is not None: thr_warn_reg = ((int(max_thr * 1000) & 0xFFFF) << 16) | ( int(min_thr * 1000) & 0xFFFF ) self.board.write_address( FRAM_BA + Warn_Thresholds[adc_measure]["add"], thr_warn_reg ) self.set_thresholds_update( f"set_current_warning_thresholds {current} {min_thr} {max_thr}" ) return True
[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 TpmMcu""" self.logger.info("TpmMcu has been initialised") return True
[docs] def status_check(self): """Perform status check. :return: Status """ self.logger.info("TpmMcu : Checking status") return Status.OK
[docs] def clean_up(self): """Perform cleanup. :return: Success """ self.logger.info("TpmMcu : Cleaning up") return True