Example #1
0
    def set_frequency(self, freq):
        """Sets the output frequency of the oscillator.
		
		:param freq: Desired frequency [10 - 945] (Megahertz)
		"""

        if not 10.0 <= freq <= 945.0:
            raise I2CException(
                "The frequency %fMHz is out of the range of this device")

        #Determine divider combination to be used
        #Min/max dividers to use based on possible oscillator frequencies
        divider_max = int(math.floor(5670.0 / freq))
        divider_min = int(math.ceil(4850.0 / freq))
        found = False

        for divider in range(divider_min, divider_max + 1):
            for hs_div in [11, 9, 7, 6, 5, 4]:
                n1 = int(float(divider) / hs_div)

                #If desired divider can be produced from HS_DIV and N1
                if n1 == float(divider) / hs_div and (n1 == 1 or n1 & 1 == 0):
                    found = True
                    self.__n1 = n1
                    self.__hs_div = hs_div
                    break
            if found:
                break
        else:
            raise I2CException(
                "There is no possible divider combination for %f MHz" % freq)

        #Calculate RFREQ from divider choice
        self.__rfreq = freq * self.__hs_div * self.__n1 / self.__fxtal

        #Freeze the oscillator
        self.write8(137, self.readU8(137) | 0x10)

        #Update device with new values
        raw_hs_div = self.__hs_div - 4
        raw_n1 = self.__n1 - 1
        raw_rfreq = int(self.__rfreq * 2**28)
        self.writeList(
            self.__register,
            map(int, [(raw_hs_div << 5) + (raw_n1 >> 2),
                      ((raw_n1 & 0b11) << 6) + ((raw_rfreq >> 32) & 0b111111),
                      (raw_rfreq >> 24) & 0xff, (raw_rfreq >> 16) & 0xff,
                      (raw_rfreq >> 8) & 0xff, raw_rfreq & 0xff]))

        #Unfreeze the oscillator and set NEWFREQ flag
        self.write8(137, self.readU8(137) & 0xEF)
        self.write8(135, 0x40)
        self.__fout = (self.__fxtal * self.__rfreq) / (self.__n1 *
                                                       self.__hs_div)
Example #2
0
    def set_wiper(self, wiper, position):
        """Manually sets a wiper position
        :param wiper: Wiper to set 0=A, 1=B
        :param position: Target position [0-255]
        """

        if not wiper in [0, 1]:
            raise I2CException("Select either wiper 0 or wiper 1")
        if position > 255:
            raise I2CException("Value greater than 255, range is 0 - 255")
        if position < 0:
            raise I2CException("Value less than 0, range is 0 - 255")

        self.__wiper_pos[wiper] = int(position)
        self.write8(wiper, self.__wiper_pos[wiper])
Example #3
0
    def attach_device(self, channel, device, *args, **kwargs):
        """Attach an I2C device to the TCA multiplexer.

        This method attaches a device to the TCA multiplexer on a specified TCA
        channel. The device must be an instance of, or type, derived from I2CDevice or
        I2CContainer. If a class is passed, a device of the appropriate type is
        initialised and returned.

        :param channel: TCA channel on which the device is present
        :param device: class or instance to attach to the TCA
        :param args: positional arguments to pass to device initialisation
        :param kwargs: keyword arguments to pass to device initialisation
        """
        # If passed a callable type for a device, initialise it having selected the appropriate
        # TCA channel
        if callable(device):
            self.write8(0, 1 << channel)
            self._selected_channel = channel
            device = device(*args, **kwargs)

        # Raise an exception if the device is not and I2CDevice or I2CContainer instance
        if not isinstance(device, I2CDevice) and not isinstance(device, I2CContainer):
            raise I2CException(
                'Device %s must be a type or an instance of I2CDevice or I2CContainer' % device)

        # Add device to attached devices and set its pre-access callback
        self._attached_devices[device] = channel
        device.pre_access = self.__device_callback
        return device
Example #4
0
    def __device_callback(self, device):
        """Internal device callback method.

        This method is called internally to allow attached devices to transparently
        select the appropriate TCA multiplexer channel. The TCA is accessed only if the
        device being accessed is not on the currently selected channel.

        :param device: the device for which the callback is being called.
        """
        # Check the device is attached, otherwise raise an exception
        if device not in self._attached_devices:
            raise I2CException('Device %s was not properly detached from the TCA' % device)

        # Call own callback (for chained TCAs)
        if self.pre_access is not None:
            self.pre_access(self)

        # Skip accessing the TCA if the current channel is already selected
        if self._attached_devices[device] == self._selected_channel:
            return

        self._selected_channel = self._attached_devices[device]

        # Write to the TCA to select the correct channel
        self.write8(0, 1 << self._attached_devices[device])
Example #5
0
    def set_resistance(self, wiper, resistance):
        """Sets the resistance of a given wiper in rheostat mode (see datasheet)
        :param wiper: Wiper to set 0=A, 1=B
        :param resistance: Desired resistance between H- and W- (Kiloohms)
        """

        if not wiper in [0, 1]:
            raise I2CException("Select either wiper 0 or wiper 1")

        if resistance < 0 or resistance > self.__tot_resistance:
            raise I2CException(
                "Select a resistance between 0 and {:.2f}".format(
                    self.__tot_resistance))

        self.__wiper_pos[wiper] = int(resistance / self.__tot_resistance *
                                      255.0)
        self.write8(wiper, self.__wiper_pos[wiper])
Example #6
0
    def get_wiper(self, wiper):
        """Gets a wiper position
        :param wiper: Wiper to get 0=A, 1=B
        :returns: Current position [0-255]
        """

        if not wiper in [0, 1]:
            raise I2CException("Select either wiper 0 or wiper 1")

        return self.__wiper_pos[wiper]
Example #7
0
    def read_dac_voltage(self, dac):
	""" reads the dac value and returns it as a voltage
	@param dac : the dac to set
	"""
        if dac == 1:
            return (self.read_dac_value(dac) * 0.00002)
        elif dac == 4:
            return (self.read_dac_value(dac) * 0.0004)
        else:
            raise I2CException("Choose DAC 1 or 4, 2/3 not currently implemented")
Example #8
0
	def set_wiper(self, wiper, position):
		"""Manually sets a wiper position
		:param wiper: Wiper to set 0=A, 1=B
		:param position: Target position [0-255]
		"""

		if not wiper in [0,1]:
                        raise I2CException("Select either wiper 0 or wiper 1")

		self.__wiper_pos[wiper] = int(position)
		self.write8(wiper, self.__wiper_pos[wiper])
Example #9
0
	def set_PD(self, wiper, pd):
		"""Sets the potential difference of a given wiper in potential divider mode (see datasheet)
		:param wiper: Wiper to set 0=A, 1=B
		:param pd: Target potential difference (Volts)
		"""

		if not wiper in [0,1]:
			raise I2CException("Select either wiper 0 or wiper 1")

		self.__wiper_pos[wiper] = int((pd - self.__low_pd[wiper]) / (self.__high_pd[wiper] - self.__low_pd[wiper]) * 256.0)
		self.write8(wiper, self.__wiper_pos[wiper])
Example #10
0
    def set_resistance(self, resistance):
        #Sets the resistance of a given wiper in rheostat mode (see datasheet)
        #:param wiper: Wiper to set 0=A, 1=B
        #:param resistance: Desired resistance between H- and W- (Kiloohms)
        #

        if resistance < 0 or resistance > self.__tot_resistance:
            raise I2CException("Select a resistance between 0 and {:.2f}".format(self.__tot_resistance))

        self.__wiper_pos = int(resistance / self.__tot_resistance * self.__num_wiper_pos)
        self.write8(((self.__wiper_pos & 0xFF00) + 0x400)>>8, (self.__wiper_pos & 0xFF))
Example #11
0
    def set_terminal_PDs(self, wiper, low, high):
        """Sets the potential difference for H- and L- on a given wiper for set_PD()
        :param wiper: Wiper to set 0=A, 1=B
        :param low: Low PD (Volts)
        :param high: High PD (Volts)
        """

        if not wiper in [0, 1]:
            raise I2CException("Select either wiper 0 or wiper 1")

        self.__low_pd[wiper] = float(low)
        self.__high_pd[wiper] = float(high)
Example #12
0
    def get_wiper(self, wiper, force=False):
        """Gets a wiper position
        :param wiper: Wiper to get 0=A, 1=B
        :returns: Current position [0-255]
        """

        if not wiper in [0, 1]:
            raise I2CException("Select either wiper 0 or wiper 1")

        if force:
            self.__wiper_pos = [self.readU8(0), self.readU8(1)]

        return self.__wiper_pos[wiper]
Example #13
0
    def remove_device(self, device):
        """Remove an I2C device from the TCA multiplexer.

        This method removes an attached device from the TCA multiplexer and clears the
        device callback to prevent TCA access for that device.

        :param device: Device to remove from the TCA.
        """
        if device not in self._attached_devices:
            raise I2CException('Device %s is not attached to this TCA' % device)

        self._attached_devices.pop(device)
        device.pre_access = None
Example #14
0
    def set_from_voltage(self, dac, voltage):
	""" sets the dac i2c value from a voltage
	@param dac : the dac number to set
	@param voltage : the voltage value to use
	""" 
        if dac == 1:
            value = voltage / 0.00002
            self.set_from_value(dac, int(value))

        elif dac == 4:
            value = voltage / 0.0004
            self.set_from_value(dac, int(value))
        else:
            raise I2CException("Choose DAC 1 or 4, 2/3 not currently implemented")    
Example #15
0
    def read_input_raw(self, channel):
        """Convert and read a raw ADC value on a channel.

        This method triggers a conversion on the specified channel and
        reads back the raw 16-bit value from the device

        :param channel: channel to convert
        :return raw conversion result
        """
        # Check legal channel requested
        if channel < 0 or channel >= self.NUM_ADC_CHANNELS:
            raise I2CException("Illegal channel {} requested".format(channel))

        # Trigger a conversion on channel, setting upper 4 bits of address pointer
        self.write8(0x70 + ((channel + 1) << 4), 0)

        # Read conversion register
        data = self.readU16(0)

        # Swap bytes to correct order
        data = ((data & 0xff) << 8) + ((data & 0xff00) >> 8)

        return data