Source code for pyfabil.plugins.tpm.clock_monitor

from __future__ import division
from builtins import str
__author__ = 'Peter Duffin'

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

[docs] class TpmClockmon(FirmwareBlock): """ FirmwareBlock tests class """ @compatibleboards(BoardMake.TpmBoard, BoardMake.Tpm16Board) @friendlyname('tpm_clock_monitor') @maxinstances(2) def __init__(self, board, **kwargs): """ TpmClockmon initialiser :param board: Pointer to board instance """ super(TpmClockmon, 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) self.clock_bit_idx = { 'JESD' : [0, 4, 8, 12], 'DDR' : [1, 5, 9, 13], 'UDP' : [2, 6, 10, 14] } self.mmcm_ctrl_bitmask = { 'C2C' : 0x1, 'JESD' : 0x2, 'DSP' : 0x4 } self.available_clocks = list(self.clock_bit_idx.keys()) self.available_clock_managers = list(self.mmcm_ctrl_bitmask.keys())
[docs] def enable_clock_monitoring(self, clock_name=None): if clock_name is None: clocks = self.available_clocks else: clocks = [clock_name] reg = self.board[f'{self._device}.drp_jesd_mmcm.monitor_interrupt_enable'] for clock in clocks: if clock.upper() not in self.available_clocks: raise PluginError(f"No clock named '{clock.upper()}' \n Options are {', '.join(self.available_clocks)} (not case sensitive)") for bit in self.clock_bit_idx.get(clock.upper(), []): reg = reg | (1<<bit) self.board[f'{self._device}.drp_jesd_mmcm.monitor_interrupt_enable'] = reg return
[docs] def disable_clock_monitoring(self, clock_name=None): if clock_name is None: clocks = self.available_clocks else: clocks = [clock_name] reg = self.board[f'{self._device}.drp_jesd_mmcm.monitor_interrupt_enable'] for clock in clocks: if clock.upper() not in self.available_clocks: raise PluginError(f"No clock named '{clock.upper()}' \n Options are {', '.join(self.available_clocks)} (not case sensitive)") for bit in self.clock_bit_idx.get(clock.upper(), []): reg = reg & ~(1<<bit) self.board[f'{self._device}.drp_jesd_mmcm.monitor_interrupt_enable'] = reg return
[docs] def check_clock_status(self, clock_name=None): if clock_name is None: clocks = self.available_clocks else: clocks = [clock_name] status = {} for clock in clocks: if clock.upper() not in self.available_clocks: raise PluginError(f"No clock named '{clock.upper()}' \n Options are {', '.join(self.available_clocks)} (not case sensitive)") status_reg = self.board[f'{self._device}.drp_jesd_mmcm.monitor_interrupt_status'] bitmask = sum([2**i for i in self.clock_bit_idx.get(clock.upper(), [])]) # Calculate bitmask from bit indexes errors = status_reg & bitmask status[clock.upper()] = not errors > 0 # True if Status OK, no errors return status
[docs] def clear_clock_status(self, clock_name=None): if clock_name is None: clocks = self.available_clocks else: clocks = [clock_name] reg = self.board[f'{self._device}.drp_jesd_mmcm.monitor_interrupt_status'] for clock in clocks: if clock.upper() not in self.available_clocks: raise PluginError(f"No clock named '{clock.upper()}' \n Options are {', '.join(self.available_clocks)} (not case sensitive)") for bit in self.clock_bit_idx.get(clock.upper(), []): reg = reg | (1<<bit) self.board[f'{self._device}.drp_jesd_mmcm.monitor_interrupt_status'] = reg return
[docs] def get_available_clocks_to_monitor(self): return self.available_clocks
[docs] def check_clock_manager_status(self, name=None): if name is None: clock_managers = self.available_clock_managers else: clock_managers = [name.upper()] status = {} for mmcm in clock_managers: if mmcm not in self.available_clock_managers: raise PluginError(f"No clock manager named '{mmcm}' \n Options are {', '.join(self.available_clock_managers)} (not case sensitive)") lock_status = self.board[f'{self._device}.regfile.mmcm_status.locked'] & self.mmcm_ctrl_bitmask[mmcm] > 0 lock_loss_cnt = self.board[f'{self._device}.regfile.mmcm_status.{mmcm.lower()}_mmcm_lock_loss_cnt'] status[f'{mmcm}_MMCM'] = (lock_status, lock_loss_cnt) return status
[docs] def clear_clock_manager_status(self, name=None): if name is None: clock_managers = self.available_clock_managers else: clock_managers = [name.upper()] reset = 0x0 for mmcm in clock_managers: if mmcm not in self.available_clock_managers: raise PluginError(f"No clock manager named '{mmcm}' \n Options are {', '.join(self.available_clock_managers)} (not case sensitive)") reset = reset | self.mmcm_ctrl_bitmask[mmcm] self.board[f'{self._device}.regfile.mmcm_status.lock_loss_cnt_reset'] = reset return
##################### Superclass method implementations #################################
[docs] def initialise(self): """ Initialise TpmClockmon """ logging.info("TpmClockmon has been initialised") return True
[docs] def status_check(self): """ Perform status check :return: Status """ logging.info("TpmClockmon : Checking status") return Status.OK
[docs] def clean_up(self): """ Perform cleanup :return: Success """ logging.info("TpmClockmon : Cleaning up") return True