Ejemplo n.º 1
0
class DevParam(object):
    """
    this class groups together:
    a) a control widget and the group into which it will be placed
    b) the BitItems of the appropriate Register(s) that the widget controls
    c) possibly, a number of "shadow" OtpParams (i.e. the "fast" and "slow"
       register concept introduced on C-Cruiser)
    """

    def __init__(self, parameter_definition=None):
        self.parameter_definition = parameter_definition
        self.name = None
        self.configuration_number = None
        self.label = None
        self.register_assignment_text = None
        self.widget_group_name = None
        self.initial_value = None

        self.widget = None
        self.widget_value = None
        self.widget_group = None
        self.is_write_read = None
        self.is_read_only = None
        self.is_trigger = None
        self.is_trim = None
        self.binary_value = None
        self.bit_items = None
        self.registers_used = None
        self.auto_update = None

        self.attribute_text = None
        self.parameter_type = None
        self.has_shadow_otp = None
        self.shadow_otp_params = None

        self.combo_box_texts = None
        if parameter_definition is not None:
            self.load_parameter_definition()
        return

    def set_value(self, value):
        self.binary_value = value
        self.calc_bit_items_from_binary()
        self.update_based_on_bit_items()
        return

    def set_shadow_otp_param_widget_value(self, shadow_number, value=None):
        votp_widget = self.shadow_otp_params[shadow_number].widget
        if value is None:
            if isinstance(votp_widget, QCheckBox):
                votp_widget.setChecked(self.widget.isChecked())
            elif isinstance(votp_widget, QSpinBox):
                votp_widget.setValue(self.widget.value())
            elif isinstance(votp_widget, QComboBox):
                votp_widget.setCurrentIndex(self.widget.currentIndex())
            elif isinstance(votp_widget, Lfsr256SpinBox):
                votp_widget.setValue(self.widget.value())
            elif isinstance(votp_widget, HexSpinBox):
                votp_widget.setValue(self.widget.value())
            else:
                print("I don't know the widget type")
        else:
            if isinstance(votp_widget, QCheckBox):
                votp_widget.setChecked(value != 0)
            elif isinstance(votp_widget, QSpinBox):
                votp_widget.setValue(value)
            elif isinstance(votp_widget, QComboBox):
                votp_widget.setCurrentIndex(value)
            elif isinstance(votp_widget, Lfsr256SpinBox):
                votp_widget.setValue(value)
            elif isinstance(votp_widget, HexSpinBox):
                votp_widget.setValue(value)
            else:
                print("I don't know the widget type")

    def setup_shadow_otp_params(self):
        """
        """
        self.shadow_otp_params = []
        if self.parameter_type == "fixed":
            num_shadows = 1
        elif self.parameter_type == "fast":
            num_shadows = 1
        elif self.parameter_type == "slow":
            num_shadows = 4
        else:
            return

        for i in range(num_shadows):
            new_otp_param = OtpParam(parent_param=self,
                                     parameter_definition=self.parameter_definition,
                                     config_number=i)
            new_otp_param.take_ownership_of_bit_items()
            new_otp_param.setup_widget()
            self.shadow_otp_params.append(new_otp_param)

            new_otp_param.update_based_on_bit_items()
        return

    def calc_binary_from_bit_items(self):
        """   add docstring here        """
        val = 0
        for i in range(len(self.bit_items)):
            val += self.bit_items[i].value * (2 ** i)
        self.binary_value = val
        return

    def calc_bit_items_from_binary(self):
        """
        Convert the binary value to a sequence of bits and load the
        """
        for i in range(len(self.bit_items)):
            if (self.binary_value & 2 ** i) != 0:
                self.bit_items[i].set_value(1)
            else:
                self.bit_items[i].set_value(0)
        return

    def calc_widget_value_from_widget(self):
        """
        add docstring here
        """
        if isinstance(self.widget, QCheckBox):
            if self.widget.checkState() == 0:
                self.widget_value = 0
            else:
                self.widget_value = 1
        elif isinstance(self.widget, QComboBox):
            self.widget_value = self.widget.currentIndex()
        elif isinstance(self.widget, QSpinBox):
            self.widget_value = self.widget.value()
        elif isinstance(self.widget, QRadioButton):
            if self.widget.isChecked():
                self.widget_value = 1
            else:
                self.widget_value = 0
        else:
            print "unknown widget called the 'widget_changed' routine"
        return

    def connect_widget_signals_to_actions(self):
        """

        """
        if isinstance(self.widget, QCheckBox):
            QObject.connect(self.widget, SIGNAL("stateChanged(int)"), self.update_based_on_widget_change)
        elif isinstance(self.widget, QComboBox):
            QObject.connect(self.widget, SIGNAL("currentIndexChanged(int)"), self.update_based_on_widget_change)
        elif isinstance(self.widget, Lfsr256SpinBox):
            QObject.connect(self.widget, SIGNAL("valueChanged(int)"), self.update_based_on_widget_change)
        elif isinstance(self.widget, HexSpinBox):
            QObject.connect(self.widget, SIGNAL("valueChanged(int)"), self.update_based_on_widget_change)
        elif isinstance(self.widget, QSpinBox):
            QObject.connect(self.widget, SIGNAL("valueChanged(int)"), self.update_based_on_widget_change)
        elif isinstance(self.widget, QRadioButton):
            QObject.connect(self.widget, SIGNAL("valueChanged(int)"), self.update_based_on_widget_change)
        elif isinstance(self.widget, QLabel):
            QObject.connect(self.widget, SIGNAL("toggled(bool)"), self.update_based_on_widget_change)
        else:
            print("unknown widget type in connect_widget_signals_to_actions")
            return

    def load_parameter_definition(self):
        """
        """
        field = self.parameter_definition
        idx = 0
        label_name = str(field[idx])
        idx += 1
        self.register_assignment_text = str(field[idx])
        idx += 1
        self.parameter_type = str(field[idx])
        idx += 1
        self.widget_group_name = str(field[idx])
        idx += 1
        base_attribute_name = str(field[idx])
        idx += 1
        instance_text = str(field[idx])
        idx += 1
        widget_type_name = str(field[idx])
        idx += 1
        self.initial_value = int(str(field[idx]))
        idx += 1
        self.is_read_only = int(str(field[idx])) != 0
        idx += 1
        tool_tip_text = str(field[idx])
        idx += 1

        self.label = QLabel()
        self.label.setText(label_name)

        # assign a configuration number
        if instance_text == "":
            pass
        else:
            self.configuration_number = int(instance_text)

        # name this parameter, adding the configuration number
        self.name = label_name.replace(" ", "_")
        if self.configuration_number is not None:
            self.name += "_" + instance_text

        self.label.setToolTip(tool_tip_text)
        self.label.setStatusTip(self.register_assignment_text)

        #
        self.attribute_text = str.lower(base_attribute_name)
        if self.configuration_number is not None:
            self.attribute_text += "_" + instance_text

        if widget_type_name == "comboBox":
            self.widget = QComboBox()
            self.combo_box_texts = []
            for i in range(idx, len(field)):
                # we just number the items in the comboBox if
                # there is no string info in the entry, else
                # we give the item the string
                self.combo_box_texts.append(field[i])

        elif widget_type_name == "spinBox":
            self.widget = QSpinBox()
        elif widget_type_name == "checkBox":
            self.widget = QCheckBox()
        elif widget_type_name == "hexSpinBox":
            self.widget = HexSpinBox()
        elif widget_type_name == "lfsr256SpinBox":
            self.widget = Lfsr256SpinBox()
        else:
            print 'dunno what this is:', widget_type_name
            return

        self.connect_widget_signals_to_actions()

        self.widget.setToolTip(self.attribute_text + ", " + tool_tip_text)
        self.widget.setStatusTip(self.register_assignment_text)
        self.widget.setWhatsThis(self.widget_group_name)
        self.widget.setEnabled(not self.is_read_only)
        return

    def connect_to_register_bits(self):
        # update the value of the widget from the bit items which
        # correspond to it
        self.widget_value = 0
        self.take_ownership_of_bit_items()
        self.update_based_on_bit_items()

        # set the minimum and maximum widget values will be,
        # based on the number of bitrs
        num_bits_in_param = len(self.bit_items)
        if isinstance(self.widget, Lfsr256SpinBox):
            pass        # the LFSR spinBox is special and already has these assigned
        elif isinstance(self.widget, QSpinBox):
            self.widget.setMinimum(0)
            self.widget.setMaximum(2 ** num_bits_in_param - 1)
        elif isinstance(self.widget, QComboBox):
            self.widget.setMaxCount(2 ** num_bits_in_param)
            for i in range(self.widget.maxCount()):
                if i < len(self.combo_box_texts):
                    self.widget.addItem(str(self.combo_box_texts[i]))
                else:
                    self.widget.addItem(str(i))
        elif isinstance(self.widget, QCheckBox):
            pass        # we don't need to do anything if it's a checkBox
        else:
            print("I don't know what this widget is:", self.widget.objectName())

        for i in range(num_bits_in_param):
            txt = self.widget.whatsThis()
            txt += ": " + self.name
            if num_bits_in_param == 1:
                self.bit_items[i].setToolTip(txt)
            else:
                txt += "[" + str(i) + "]"
                self.bit_items[i].setToolTip(txt)

    def set_widget_to_correct_display(self):
        """   add docstring here        """
        if isinstance(self.widget, QCheckBox):
            if self.widget_value == 0:
                self.widget.setChecked(False)
            else:
                self.widget.setChecked(True)
        elif isinstance(self.widget, QComboBox):
            self.widget.setCurrentIndex(self.widget_value)
        elif isinstance(self.widget, QSpinBox):
            self.widget.setValue(self.widget_value)
        elif isinstance(self.widget, QRadioButton):
            if self.widget_value == 0:
                self.widget.setChecked(False)
            else:
                self.widget.setChecked(True)
        elif isinstance(self.widget, QLabel):
            self.widget.setText(number_to_decimal_string(self.widget_value, 8, False))
        return

    def set_auto_update(self, st=True):
        """
        """
        self.auto_update = st

    def take_ownership_of_bit_items(self):
        """
        From the statusTip text (e.g. DIV1_H[2:0], DIV1_L[7:0], or POWER[3])
        figure out which bit items belong to this parameter instance and
        take ownership of those bit items
        """
        # the bits may be in one register, or they may be scattered across
        # multiple registers, so we split the bits into separate ranges if
        # necessary

        self.registers_used = []
        self.bit_items = []
        ranges = self.widget.statusTip().replace(" ", "").split(";")

        # next, we take each range and separate it into the register name and
        # a list of bit positions in that register
        for rng in ranges:
            register_name_strng, temp = rng.split("[")
            bit_range_strng = str("[") + temp
            this_reg = REGISTERS_BY_NAME_DICT[register_name_strng]
            if this_reg not in self.registers_used:
                self.registers_used.append(this_reg)

            temp = bit_range_strng[1:-1].split(":")

            if len(temp) == 2:
                msb_strng, lsb_strng = temp
                lsb = int(lsb_strng)
                msb = int(msb_strng)
            else:
                lsb = int(temp[0])
                msb = lsb

            for bit_offset in range(msb, lsb - 1, -1):
                this_bit_item = this_reg.bit_items_lsb_first[bit_offset]
                if this_bit_item.parameter_owner is not None:
                    print "----"
                    print register_name_strng, temp
                    print "this register bit has already been assigned"
                    break
                this_bit_item.parameter_owner = self

                if self.is_read_only:
                    this_bit_item.setBackground(QBrush(Qt.cyan))
                    this_bit_item.toggling_is_enabled = False
                else:
                    this_bit_item.setBackground(QBrush(Qt.yellow))
                    this_bit_item.toggling_is_enabled = True
                self.bit_items.append(this_bit_item)
        self.bit_items.reverse()
        return

    def update_based_on_bit_items(self):
        """
        This is called when any of the parameters "bit items" has changed
        to synchronize the other attributes of the parameter (i.e the
        binary value, widget value, and widget itself) with the bit items.
        """
        self.calc_binary_from_bit_items()
        self.widget_value = self.binary_value
        self.set_widget_to_correct_display()
        return

    def update_based_on_widget_change(self):
        """
        This is called when the widget is changed to synchronize the other
        attributes of the parameter (i.e the widget value, binary value,
        and bit items) with the widget.

        """
        if not self.is_read_only:
            self.calc_widget_value_from_widget()
            self.binary_value = self.widget_value
            self.calc_bit_items_from_binary()
            if self.auto_update:
                for reg in self.registers_used:
                    reg.write_and_readback()
        return
Ejemplo n.º 2
0
class OtpParam(object):
    """

    """
    def __init__(self, parent_param=None, parameter_definition=None, config_number=None):
        self.parent_param = parent_param
        self.parameter_definition = parameter_definition
        self.config_number = config_number

        self.name = None
        self.configuration_number = None
        self.label = None
        self.register_assignment_text = None
        self.widget_group_name = None
        self.initial_value = None

        self.widget = None
        self.widget_value = None
        self.widget_group = None
        self.is_write_read = None
        self.is_read_only = None
        self.is_trigger = None
        self.is_trim = None
        self.binary_value = None
        self.bit_items = None
        self.registers_used = None
        self.auto_update = None

        self.attribute_text = None
        self.parameter_type = None

        self.combo_box_texts = None
        if parameter_definition is not None:
            self.load_parameter_definition()
        return

    def setup_widget(self):
        num_bits_in_param = len(self.bit_items)
        if isinstance(self.widget, Lfsr256SpinBox):
            # the LFSR spinBox is special and already has these assigned
            pass
        elif isinstance(self.widget, QSpinBox):
            self.widget.setMinimum(0)
            self.widget.setMaximum(2 ** num_bits_in_param - 1)
        elif isinstance(self.widget, QComboBox):
            self.widget.setMaxCount(2 ** num_bits_in_param)
            for i in range(self.widget.maxCount()):
                if i < len(self.combo_box_texts):
                    self.widget.addItem(str(self.combo_box_texts[i]))
                else:
                    self.widget.addItem(str(i))
        elif isinstance(self.widget, QCheckBox):
            # we don't need to do anything if it's a checkBox
            pass
        else:
            print("I don't know what this widget is:", self.widget.objectName())

    def set_value(self, value):
        self.binary_value = value
        self.calc_bit_items_from_binary()
        self.update_based_on_bit_items()
        return

    def calc_binary_from_bit_items(self):
        """   add docstring here        """
        val = 0
        for i in range(len(self.bit_items)):
            val += self.bit_items[i].value * (2 ** i)
        self.binary_value = val
        return

    def calc_bit_items_from_binary(self):
        """
        Convert the binary value to a sequence of bits and load the
        """
        for i in range(len(self.bit_items)):
            if (self.binary_value & 2 ** i) != 0:
                self.bit_items[i].set_value(1)
            else:
                self.bit_items[i].set_value(0)
        return

    def calc_widget_value_from_widget(self):
        """
        add docstring here
        """
        if isinstance(self.widget, QCheckBox):
            if self.widget.checkState() == 0:
                self.widget_value = 0
            else:
                self.widget_value = 1
        elif isinstance(self.widget, QComboBox):
            self.widget_value = self.widget.currentIndex()
        elif isinstance(self.widget, QSpinBox):
            self.widget_value = self.widget.value()
        elif isinstance(self.widget, QRadioButton):
            if self.widget.isChecked():
                self.widget_value = 1
            else:
                self.widget_value = 0
        else:
            print "unknown widget called the 'widget_changed' routine"
        return

    def connect_widget_signals_to_actions(self):
        """
        """
        if isinstance(self.widget, QCheckBox):
            QObject.connect(self.widget, SIGNAL("stateChanged(int)"), self.update_based_on_widget_change)
        elif isinstance(self.widget, QComboBox):
            QObject.connect(self.widget, SIGNAL("currentIndexChanged(int)"), self.update_based_on_widget_change)
        elif isinstance(self.widget, Lfsr256SpinBox):
            QObject.connect(self.widget, SIGNAL("valueChanged(int)"), self.update_based_on_widget_change)
        elif isinstance(self.widget, HexSpinBox):
            QObject.connect(self.widget, SIGNAL("valueChanged(int)"), self.update_based_on_widget_change)
        elif isinstance(self.widget, QSpinBox):
            QObject.connect(self.widget, SIGNAL("valueChanged(int)"), self.update_based_on_widget_change)
        elif isinstance(self.widget, QRadioButton):
            QObject.connect(self.widget, SIGNAL("valueChanged(int)"), self.update_based_on_widget_change)
        elif isinstance(self.widget, QLabel):
            QObject.connect(self.widget, SIGNAL("toggled(bool)"), self.update_based_on_widget_change)
        else:
            print("unknown widget type in connect_widget_signals_to_actions")
            return

    def load_parameter_definition(self):
        """
        """
        field = self.parameter_definition
        idx = 0
        label_name = str(field[idx])
        idx += 1
        self.register_assignment_text = str(field[idx])
        idx += 1
        self.parameter_type = str(field[idx])
        idx += 1
        self.widget_group_name = str(field[idx])
        idx += 1
        base_attribute_name = str(field[idx])
        idx += 1
        instance_text = str(field[idx])
        idx += 1
        widget_type_name = str(field[idx])
        idx += 1
        self.initial_value = int(str(field[idx]))
        idx += 1
        self.is_read_only = int(str(field[idx])) != 0
        idx += 1
        tool_tip_text = str(field[idx])
        idx += 1

        self.label = QLabel()
        self.label.setText(label_name)

        # assign a configuration number
        if instance_text == "":
            pass
        else:
            self.configuration_number = int(instance_text)

        # name this parameter, adding the configuration number
        self.name = label_name.replace(" ", "_")
        if self.configuration_number is not None:
            self.name += "_" + instance_text

        self.label.setToolTip(tool_tip_text)
        self.label.setStatusTip(self.register_assignment_text)

        #
        self.attribute_text = str.lower(base_attribute_name)
        if self.configuration_number is not None:
            self.attribute_text += "_" + instance_text

        if widget_type_name == "comboBox":
            self.widget = QComboBox()
            self.combo_box_texts = []
            for i in range(idx, len(field)):
                # we just number the items in the comboBox if
                # there is no string info in the entry, else
                # we give the item the string
                self.combo_box_texts.append(field[i])

        elif widget_type_name == "spinBox":
            self.widget = QSpinBox()
        elif widget_type_name == "checkBox":
            self.widget = QCheckBox()
        elif widget_type_name == "hexSpinBox":
            self.widget = HexSpinBox()
        elif widget_type_name == "lfsr256SpinBox":
            self.widget = Lfsr256SpinBox()
        else:
            print 'dunno what this is:', widget_type_name
            return

        self.connect_widget_signals_to_actions()

        self.widget.setToolTip(self.attribute_text + ", " + tool_tip_text)
        self.widget.setStatusTip(self.register_assignment_text)
        self.widget.setWhatsThis(self.widget_group_name)
        self.widget.setEnabled(not self.is_read_only)
        return

    def set_widget_to_correct_display(self):
        """   add docstring here        """
        if isinstance(self.widget, QCheckBox):
            if self.widget_value == 0:
                self.widget.setChecked(False)
            else:
                self.widget.setChecked(True)
        elif isinstance(self.widget, QComboBox):
            self.widget.setCurrentIndex(self.widget_value)
        elif isinstance(self.widget, QSpinBox):
            self.widget.setValue(self.widget_value)
        elif isinstance(self.widget, QRadioButton):
            if self.widget_value == 0:
                self.widget.setChecked(False)
            else:
                self.widget.setChecked(True)
        elif isinstance(self.widget, QLabel):
            self.widget.setText(number_to_decimal_string(self.widget_value, 8, False))
        return

    def set_auto_update(self, st=True):
        """
        """
        self.auto_update = st

    def take_ownership_of_bit_items(self):
        """
        From the statusTip text (e.g. DIV1_H[2:0], DIV1_L[7:0], or POWER[3])
        figure out which bit items belong to this parameter instance and
        take ownership of those bit items
        """
        # the bits may be in one register, or they may be scattered across
        # multiple registers, so we split the bits into separate ranges if
        # necessary

        self.registers_used = []
        self.bit_items = []

        for bit_item in self.parent_param.bit_items:
            parent_offset = bit_item.register_owner.offset
            if self.parameter_type == "slow":
                otp_offset = parent_offset - OTP_START_ADDRESS + (self.config_number * 19)
            elif self.parameter_type == "fast":
                otp_offset = parent_offset - OTP_START_ADDRESS
            elif self.parameter_type == "fixed":
                otp_offset = parent_offset - OTP_START_ADDRESS
            else:
                print "unknown parameter type: ", self.parameter_type
                return

            otp_bit_position = bit_item.bit_position
            # print bit_item.register_owner.name, parent_offset
            otp_stage_reg = OTPBYTES_BY_OFFSET_DICT[otp_offset]
            if otp_stage_reg not in self.registers_used:
                self.registers_used.append(otp_stage_reg)
            this_bit_item = otp_stage_reg.bit_items_lsb_first[otp_bit_position]

            if this_bit_item.parameter_owner is not None:
                print "----"
                print "this otp stage bit has already been assigned"
                break

            this_bit_item.setBackground(QBrush(Qt.yellow))
            this_bit_item.toggling_is_enabled = True

            this_bit_item.parameter_owner = self
            self.bit_items.append(this_bit_item)
        return

    def update_based_on_bit_items(self):
        """
        This is called when any of the parameters "bit items" has changed
        to synchronize the other attributes of the parameter (i.e the
        binary value, widget value, and widget itself) with the bit items.
        """
        self.calc_binary_from_bit_items()
        self.widget_value = self.binary_value
        self.set_widget_to_correct_display()
        return

    def update_based_on_widget_change(self):
        """
        This is called when the widget is changed to synchronize the other
        attributes of the parameter (i.e the widget value, binary value,
        and bit items) with the widget.

        """
        if not self.is_read_only:
            self.calc_widget_value_from_widget()
            self.binary_value = self.widget_value
            self.calc_bit_items_from_binary()
            if self.auto_update:
                for reg in self.registers_used:
                    reg.write_and_readback()
        return