コード例 #1
0
class MCP3008(object):
    """
    MCP3008 ADC (Analogue-to-Digital converter).
    """
    def __init__(self, bus=0, device=0, channel=0):
        self.bus = bus
        self.device = device
        self.channel = channel
        self.spi = SpiDev()

    def __enter__(self):
        self.open()
        return self

    def open(self):
        self.spi.open(self.bus, self.device)

    def read(self):
        adc = self.spi.xfer2([1, (8 + self.channel) << 4, 0])
        data = ((adc[1] & 3) << 8) + adc[2]
        return data

    def __exit__(self, type, value, traceback):
        self.close()

    def close(self):
        self.spi.close()
コード例 #2
0
class SPIDataLink(DataLink):
    """Clase que gestiona un enlace Serial Peripheral Interface (SPI).

    :param max_speed: máxima velocidad en herzios del enlace de datos.
    :param bus: Identificador del bus SPI que se usa para el enlace de datos.
    :param device: Línea de selección de chip SPI activa en el enlace de datos.

    Ejemplo de uso para pedir una medida del primer canal analógico de un
    conversor ADC MCP3202 conectado a la línea de selección de chip 0 de Raspberry Pi:

    >>> from pida.links import SPIDataLink
    >>> link = SPIDataLink(1000000, 0, 0)
    >>> link.open()
    >>> request = [1, 2 << 6, 0]
    >>> response = link.transfer(request)
    >>> link.close()
    """
    def __init__(self, max_speed, bus, device):
        DataLink.__init__(self, max_speed)
        self._bus = bus
        self._device = device
        self._spi = SpiDev()
        
    @property
    def bus(self):
        """Identificador del bus SPI que se usa para el enlace de datos.

        .. note:: Raspberry Pi ofrece a través de su puerto GPIO
                  un único bus SPI cuyo identificador es 0.

        Es una propiedad de sólo lectura.
        """
        return self._bus

    @property
    def device(self):
        """Línea de selección de chip SPI activa en el enlace de datos.

        .. note:: El bus SPI 0 de Raspberry Pi puede, a través del puerto GPIO,
                  activar dos líneas de selección de chip SPI: 0 y 1.

        Es una propiedad de sólo lectura.
        """
        return self._device

    def open(self):
        self._spi.open(self._bus, self._device)
        self._spi.max_speed_hz = self.max_speed

    def close(self):
        self._spi.close()

    def transfer(self, data):
        return self._spi.xfer2(data)
コード例 #3
0
ファイル: mcp3008.py プロジェクト: stevelorenz/codes-on-rasp
class MCP3008(object):

    """Class for MCP3008 ADC"""

    def __init__(self, port=0, device=0):
        self.spi = SpiDev()
        # connect spi object to specified spi device
        self.spi.open(port, device)

    def readValueChannel(self, channel=0):
        """
        read SPI data from MCP3008 on channel -> digital value
            spi.xfer2() send three bytes to the device
                the first byte is 1 -> 00000001
                the second byte is 8 + channel and left shift with 4 bits
                the third byte is 0 -> 00000000
            the device return 3 bytes as responce
        """
        # perform spi transaction
        adc = self.spi.xfer2([1, (8 + channel) <<4, 0])
        # extract value from data bytes
        data = ((adc[1] & 3) << 8) + adc[2]
        return data

    def readVoltChannel(self, channel=0, vmax=3.3, places=5):
        """
        read the digital data from MCP3008 and convert it to voltage
            MCP3008: 10bit ADC -> value in number range 0-1023
            spi value -> voltage
                   0  ->  0v
                1023  ->  vmax
        """
        # read spi digital value
        adc = self.spi.xfer2([1, (8 + channel) <<4, 0])
        data = ((adc[1] & 3) << 8) + adc[2]
        # convert it to voltage
        volts = (data * vmax) / float(1023)
        # round to specified number of decimal places
        volts = round(volts, places)
        return volts
コード例 #4
0
class SpiDevice(object):
    def __init__(self, bus, device):
        self.spi = SpiDev()
        self.bus = bus
        self.device = device

    def init(self):
        self.spi.open(self.bus, self.device)

    def transfer(self, data):
        return self.spi.xfer2(data)

    def close(self):
        self.spi.close()
コード例 #5
0
ファイル: MCP3008.py プロジェクト: joneskys7/pi
class MCP3008:
    def __init__(self, bus = 0, device = 0):
        self.bus, self.device = bus, device
        self.spi = SpiDev()
        self.open()

    def open(self):
        self.spi.open(self.bus, self.device)
    
    def read(self, channel = 0):
        adc = self.spi.xfer2([1, (8 + channel) << 4, 0])
        data = ((adc[1] & 3) << 8) + adc[2]
        return data
            
    def close(self):
        self.spi.close()
コード例 #6
0
class MCP3008:
    def __init__(self, bus = 0, device = 0, channel = 0):
        self.bus, self.device, self.channel = bus, device, channel
        self.spi = SpiDev()

    def __enter__(self):
        self.open()
        return self

    def open(self):
        self.spi.open(self.bus, self.device)

    def read(self):
        adc = self.spi.xfer2([1, (8 + self.channel) << 4, 0])
        data = ((adc[1] & 3) << 8) + adc[2]
        return data

    def __exit__(self, type, value, traceback):
        self.close()

    def close(self):
        self.spi.close()
コード例 #7
0
class MCP3008:
    def __init__(self, bus = 0, device = 0, channel = 0):
        self.bus, self.device, self.channel = bus, device, channel
        self.spi = SpiDev()

    def __enter__(self):
        self.open()
        return self

    def open(self):
        self.spi.open(self.bus, self.device)
    
    def read(self):
        adc = self.spi.xfer2([1, (8 + self.channel) << 4, 0])
        data = ((adc[1] & 3) << 8) + adc[2]
        return data

    def __exit__(self, type, value, traceback):
            self.close()
            
    def close(self):
        self.spi.close()
コード例 #8
0
class MCP3008:
    def __init__(self, bus, device, max_speed_hz=1000000):
        self.bus = bus
        self.device = device
        self.spi = SpiDev()
        self.open()
        self.spi.max_speed_hz = max_speed_hz

    def open(self, max_speed_hz=1000000):
        self.spi.open(self.bus, self.device)
        self.spi.max_speed_hz = max_speed_hz

    def read(self, channel):
        cmd1 = 4 | 2 | ((channel & 4) >> 2)
        cmd2 = (channel & 3) << 6

        adc = self.spi.xfer2([cmd1, cmd2, 0])
        data = ((adc[1] & 15) << 8) + adc[2]
        return data

    def close(self):
        self.spi.close()
コード例 #9
0
class ADC:
    """Analog joystick attached to a MCP3008 A/D converter."""
    def __init__(
        self,
        bus=1,
        channel=0,
        device=1,
    ):
        """Define which SPI device is the A/D Converter on."""
        self.bus = bus
        self.device = device
        self.channel = channel
        self.spi = SpiDev()

    def open(self):
        """Claim the SPI channel when asked."""
        self.spi.open(self.bus, self.device)
        self.spi.max_speed_hz = 1000000
        self.spi.mode = 0b00

    def read(self):
        """Ask the device for a reading on a channel."""
        adc = self.spi.xfer2([1, (8 + self.channel) << 4, 0])
        data = ((adc[1] & 3) << 8) + adc[2]
        return data

    def close_spi(self):
        """Close the SPI channel when asked."""
        self.spi.close()

    def __enter__(self):
        """Magic function if you use 'with'."""
        self.open()
        return self

    def __exit__(self, type, value, traceback):
        """Magic function if you use 'with'."""
        self.close_spi()
コード例 #10
0
class MCP3008:
    def __init__(self, bus=0, device=0):
        self.bus, self.device = bus, device
        self.spi = SpiDev()
        self.open()

    def open(self):
        self.spi.open(self.bus, self.device)
        self.spi.max_speed_hz = 1000000  # ab Raspbian-Version "Buster" erforderlich!

    def read(self, channel=0):
        adc = self.spi.xfer2([1, (8 + channel) << 4, 0])
        if 0 <= adc[1] <= 3:
            data = ((adc[1] & 3) << 8) + adc[2]
            per = (
                918 - data
            ) / 918 * 100  # maximalen Wert testen und 2x eintragen, zB 918; Wert kann nie mehr als 1023 sein!
            return per
        else:
            return 0

    def close(self):
        self.spi.close()
コード例 #11
0
class Temperature(object):
    def __init__(self, major=0, minor=0):
        self.spi = SpiDev()
        self.spi.open(major, minor)

    def rawread(self):
        return self.spi.xfer2([0, 0])

    def read(self):
        return self.calc_temp(self.rawread())

    @staticmethod
    def calc_temp(buf):
        return (((buf[0] << 8) | buf[1]) >> 3) * 0.0625

    def cleanup(self):
        self.spi.close()

    def __enter__(self):
        return self

    def __exit__(self, type_, value, traceback):
        self.cleanup()
コード例 #12
0
class MCP3201:
    def __init__(self):
        self.bus = SpiDev()
        self.bus.open(0, 0)
        self._average = 50

    def close(self):
        self.bus.close()

    def __enter__(self):
        return self

    def __exit__(self, *args):
        self.close()

    def __str__(self):
        return '<Device class {0}>'.format(self.__class__)

    @property
    def average(self):
        return self._average

    @average.setter
    def average(self, value):
        self._average = value

    def get_analog_value(self):
        result = []
        for i in range(self._average):
            adc = self.bus.xfer2([0, 0])
            adc = ((adc[0] & 0x1F) << 7) | (adc[1] >> 1)
            result.append(adc)
        return sum(result) / self._average

    def get_voltage(self, aref):
        return (self.get_analog_value() * aref / 4096)
コード例 #13
0
class MCP3008:
    def __init__(self, bus = 0, device = 0):
        self.bus, self.device = bus, device
        self.spi = SpiDev()
        self.open()
        self.spi.max_speed_hz = 1000000 # 1MHz

    def open(self):
        self.spi.open(self.bus, self.device)
        self.spi.max_speed_hz = 1000000 # 1MHz
    
    def read(self, channel = 0):
        #cmd1 = 4 | 2 | (( channel & 4) >> 2)
        #cmd2 = (channel & 3) << 6

        #adc = self.spi.xfer2([cmd1, cmd2, 0])
        #data = ((adc[1] & 15) << 8) + adc[2]
        
        adc = self.spi.xfer2([1,(8+channel)<<4,0])
        data = ((adc[1]&3) << 8) + adc[2]
        return data
            
    def close(self):
        self.spi.close()
コード例 #14
0
class LocalPiHardwareSPI(SPI):
    def __init__(self, clock_pin, mosi_pin, miso_pin, select_pin, pin_factory):
        self._port, self._device = spi_port_device(clock_pin, mosi_pin,
                                                   miso_pin, select_pin)
        self._bus = None
        if SpiDev is None:
            raise ImportError('failed to import spidev')
        super().__init__(pin_factory=pin_factory)
        to_reserve = {clock_pin, select_pin}
        if mosi_pin is not None:
            to_reserve.add(mosi_pin)
        if miso_pin is not None:
            to_reserve.add(miso_pin)
        self.pin_factory.reserve_pins(self, *to_reserve)
        self._bus = SpiDev()
        self._bus.open(self._port, self._device)
        self._bus.max_speed_hz = 500000

    def close(self):
        if self._bus is not None:
            self._bus.close()
        self._bus = None
        self.pin_factory.release_all(self)
        super().close()

    @property
    def closed(self):
        return self._bus is None

    def __repr__(self):
        try:
            self._check_open()
            return 'SPI(port=%d, device=%d)' % (self._port, self._device)
        except DeviceClosed:
            return 'SPI(closed)'

    def transfer(self, data):
        """
        Writes data (a list of integer words where each word is assumed to have
        :attr:`bits_per_word` bits or less) to the SPI interface, and reads an
        equivalent number of words, returning them as a list of integers.
        """
        return self._bus.xfer2(data)

    def _get_clock_mode(self):
        return self._bus.mode

    def _set_clock_mode(self, value):
        self._bus.mode = value

    def _get_lsb_first(self):
        return self._bus.lsbfirst

    def _set_lsb_first(self, value):
        self._bus.lsbfirst = bool(value)

    def _get_select_high(self):
        return self._bus.cshigh

    def _set_select_high(self, value):
        self._bus.cshigh = bool(value)

    def _get_bits_per_word(self):
        return self._bus.bits_per_word

    def _set_bits_per_word(self, value):
        self._bus.bits_per_word = value

    def _get_rate(self):
        return self._bus.max_speed_hz

    def _set_rate(self, value):
        self._bus.max_speed_hz = int(value)
コード例 #15
0
class CC2500(object):

    REG_MARCSTATE = 0xC0 | 0x35
    CMD_SRES = 0x30
    CMD_SFSTXON = 0x31
    CMD_SXOFF = 0x32
    CMD_XCAL = 0x33
    CMD_SRX = 0x34
    CMD_STX = 0x35
    CMD_SIDLE = 0x36
    CMD_SWOR = 0x38
    CMD_SPWD = 0x39
    CMD_SFRX = 0x3A
    CMD_SFTX = 0x3B
    CMD_SWORRST = 0x3C
    CMD_SNOP = 0x3D
    CMD_PATABLE = 0x3E
    CMD_TXFIFO = 0x3F

    CMD_SINGLE_WRITE = 0x00
    CMD_BRUST_WRITE = 0x40
    CMD_SINGLE_READ = 0x80
    CMD_BRUST_READ = 0xC0

    # get Main Radio Control State Machine State
    def __init__(self, bus=0, channel_select=1):
        self.bus = SpiDev()
        self.bus.open(bus, channel_select)
        self.reset()

    ##
    ## COMMAND
    ##
    def STX(self):
        self.bus.xfer2([self.CMD_STX])

    def SRX(self):
        self.bus.xfer2([self.CMD_SRX])

    def SIDLE(self):
        self.bus.xfer2([self.CMD_SIDLE])

    def SFRX(self):
        self.bus.xfer2([self.CMD_SFRX])

    def SFTX(self):
        self.bus.xfer2([self.CMD_SFTX])

    def SRES(self):
        self.bus.xfer2([self.CMD_SRES])

    ## Access REG

    def get_STATE(self):
        return self.bus.xfer2([0xC0 | 0x35, 0x00])[1]

    def get_RXBYTES(self):
        return self.bus.xfer2([0xC0 | 0x3B, 0x00])[1]

    def write_TXFIFO(self, package):
        tmp = []
        if type(package) == str:
            tmp = [ord(i) for i in package]
        else:
            tmp = list(package)
        tmp = [self.CMD_TXFIFO | self.CMD_BRUST_WRITE, len(tmp)] + tmp
        self.bus.xfer2(tmp)  # write package to fifo buffer (max 64byte)

    def read_RXFIFO(self):
        len_FIFO = self.get_RXBYTES()
        return self.bus.xfer2(
            [self.CMD_BRUST_READ | 0x3F for i in range(len_FIFO)])

    def reset(self):
        self.SRES()

        reg_config = [
            0x29, 0x2E, 0x06, 0x07, 0xD3, 0x91, 0x61, 0x04, 0x45, 0x00, 0x00,
            0x09, 0x00, 0x5E, 0xC4, 0xEC, 0x2C, 0x22, 0x73, 0x22, 0xF8, 0x01,
            0x07, 0x00, 0x18, 0x1D, 0x1C, 0xC7, 0x00, 0xB2, 0x87, 0x6B, 0xF8,
            0xB6, 0x10, 0xEB, 0x0B, 0x1D, 0x11, 0x41, 0x00, 0x59, 0x7F, 0x3C,
            0x88, 0x31, 0x0B
        ]

        for reg, val in enumerate(reg_config):
            self.bus.xfer2([reg, val])

        self.SIDLE()
        self.SFRX()
        self.SFTX()

    def read_config(self):
        reg_config = []
        for reg in range(49):
            val = self.bus.xfer2([0x80 | reg, 0x00])[1]
            reg_config.append(val)
        return reg_config

    ## USER API

    def write(self, package):
        self.write_TXFIFO(package)
        if (self.get_STATE() == 22):
            self.SFTX()
            self.SIDLE()
            return -1
        self.STX()
        return 0

    def read(self):
        self.reset()
        self.SRX()
        while (True):
            sleep(0.1)
            state = self.get_STATE()
            if (state in [13, 14, 15]):
                continue
            elif (state == 1):
                res = self.read_RXFIFO()
                return res
            elif (state == 17):
                self.SFRX()
                self.SIDLE()
                return -1
コード例 #16
0
ファイル: spi.py プロジェクト: DougMHu/vIoThackathon
class SPIHardwareInterface(Device):
    def __init__(self, port, device):
        self._device = None
        super(SPIHardwareInterface, self).__init__()
        # XXX How can we detect conflicts with existing GPIO instances? This
        # isn't ideal ... in fact, it's downright crap and doesn't guard
        # against conflicts created *after* this instance, but it's all I can
        # come up with right now ...
        conflicts = (11, 10, 9, (8, 7)[device])
        with _PINS_LOCK:
            for pin in _PINS:
                if pin.number in conflicts:
                    raise GPIOPinInUse(
                        'pin %r is already in use by another gpiozero object' % pin
                    )
        self._device_num = device
        self._device = SpiDev()
        self._device.open(port, device)
        self._device.max_speed_hz = 500000

    def close(self):
        if self._device:
            try:
                self._device.close()
            finally:
                self._device = None
        super(SPIHardwareInterface, self).close()

    @property
    def closed(self):
        return self._device is None

    def __repr__(self):
        try:
            self._check_open()
            return (
                "hardware SPI on clock_pin=11, mosi_pin=10, miso_pin=9, "
                "select_pin=%d" % (
                    8 if self._device_num == 0 else 7))
        except DeviceClosed:
            return "hardware SPI closed"

    def read(self, n):
        return self.transfer((0,) * n)

    def write(self, data):
        return len(self.transfer(data))

    def transfer(self, data):
        """
        Writes data (a list of integer words where each word is assumed to have
        :attr:`bits_per_word` bits or less) to the SPI interface, and reads an
        equivalent number of words, returning them as a list of integers.
        """
        return self._device.xfer2(data)

    def _get_clock_mode(self):
        return self._device.mode

    def _set_clock_mode(self, value):
        self._device.mode = value

    def _get_clock_polarity(self):
        return bool(self.mode & 2)

    def _set_clock_polarity(self, value):
        self.mode = self.mode & (~2) | (bool(value) << 1)

    def _get_clock_phase(self):
        return bool(self.mode & 1)

    def _set_clock_phase(self, value):
        self.mode = self.mode & (~1) | bool(value)

    def _get_lsb_first(self):
        return self._device.lsbfirst

    def _set_lsb_first(self, value):
        self._device.lsbfirst = bool(value)

    def _get_select_high(self):
        return self._device.cshigh

    def _set_select_high(self, value):
        self._device.cshigh = bool(value)

    def _get_bits_per_word(self):
        return self._device.bits_per_word

    def _set_bits_per_word(self, value):
        self._device.bits_per_word = value

    clock_polarity = property(_get_clock_polarity, _set_clock_polarity)
    clock_phase = property(_get_clock_phase, _set_clock_phase)
    clock_mode = property(_get_clock_mode, _set_clock_mode)
    lsb_first = property(_get_lsb_first, _set_lsb_first)
    select_high = property(_get_select_high, _set_select_high)
    bits_per_word = property(_get_bits_per_word, _set_bits_per_word)
コード例 #17
0
ファイル: leds.py プロジェクト: eltariel/njak
class Lights:
    """
    A collection of APA102 LEDs.
    """
    def __init__(self, led_indexes):
        """
        Create the LED controller.

        :param led_indexes: physical -> logical LED mapping: led_indexes[n] = LED number
        """
        self.spi = SpiDev()
        self.spi.open(0, 0)
        self.spi.max_speed_hz = 1000000

        self.pixels = [Pixel(n) for n in range(len(led_indexes))]
        self.mapping = led_indexes

        atexit.register(self._on_exit)

    def set_pixel(self, index, r, g, b, brightness=None):
        """
        Set pixel colour.

        :param index: logical index of the LED
        :param r: Red
        :param g: Green
        :param b: Blue
        :param brightness: Optional brightness value
        """
        pixel = self.get_pixel(index)
        pixel.set(r, g, b, brightness)

    def set_brightness(self, brightness, index=None):
        """
        Set global brightness.

        :param brightness: Global brightness value.
        :param index: Optional LED to address. If None, sets brightness for the whole string.
        """
        b = round(brightness)
        if index is None:
            for p in self.pixels:
                p.set_brightness(b)
        else:
            self.get_pixel(index).set_brightness(b)

    def get_pixel(self, index):
        """
        Gets the pixel at a given index.

        :param index: The index of the pixel.
        :return: The pixel.
        """
        return self.pixels[self.mapping[index]]

    def clear(self):
        """
        Blank all LEDs.
        """
        for p in self.pixels:
            p.set(0, 0, 0)

    def show(self):
        """
        Send the current pixel data to the LEDs
        """
        buf = [0x00 for _ in range(8)]
        for p in self.pixels:
            buf += p.raw()

        buf += [0xFF for _ in range(8)]
        self.spi.xfer2(buf)

    def _on_exit(self):
        self.clear()
        self.show()
コード例 #18
0
ファイル: links.py プロジェクト: noeldiazro/pida
class SPIDataLink(FullDuplexDataLink):
    """Clase que gestiona un enlace Serial Peripheral Interface (SPI).

    :param bus: Identificador del bus SPI que se usa para el enlace de datos.
    :param device: Línea de selección de chip SPI activa en el enlace de datos.
    :param configuration: Configuración del enlace de datos

    Ejemplo de uso:

    >>> from pida.links import SPIDataLinkConfiguration, SPIDataLink
    >>> configuration = SPIDataLinkConfiguration(mode=0, max_speed_hz=32000000)
    >>> with SPIDataLink(0, 0, configuration) as link:
            request = [0x00, 0x01, 0xFF]
            response = link.transfer(request)
    >>> response
    [0, 1, 255]
    """
    def __init__(self, bus, device, configuration):
        self._bus = bus
        self._device = device
        self._configuration = configuration
        self._spi = SpiDev()

    def _apply_configuration(self):
        self._spi.mode = self._configuration.mode
        self._spi.max_speed_hz = self._configuration.max_speed_hz

    @property
    def bus(self):
        """Identificador del bus SPI que se usa para el enlace de datos.

        .. note:: Raspberry Pi ofrece a través de su puerto GPIO
                  un único bus SPI cuyo identificador es 0.

        Es una propiedad de sólo lectura.
        """
        return self._bus

    @property
    def device(self):
        """Línea de selección de chip SPI activa en el enlace de datos.

        .. note:: El bus SPI 0 de Raspberry Pi puede, a través del puerto GPIO,
                  activar dos líneas de selección de chip SPI: 0 y 1.

        Es una propiedad de sólo lectura.
        """
        return self._device

    def open(self):
        self._spi.open(self._bus, self._device)
        self._apply_configuration()

    def close(self):
        self._spi.close()

    def transfer(self, data):
        return self._spi.xfer2(data)

    def __enter__(self):
        self.open()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()

    @property
    def max_speed_hz(self):
        return self._configuration.max_speed_hz

    @property
    def mode(self):
        return self._configuration.mode
コード例 #19
0
ファイル: local.py プロジェクト: DirkUK/python-gpiozero
class LocalPiHardwareSPI(SPI, Device):
    def __init__(self, factory, port, device):
        self._port = port
        self._device = device
        self._interface = None
        if SpiDev is None:
            raise ImportError('failed to import spidev')
        super(LocalPiHardwareSPI, self).__init__()
        pins = SPI_HARDWARE_PINS[port]
        self.pin_factory.reserve_pins(
            self,
            pins['clock'],
            pins['mosi'],
            pins['miso'],
            pins['select'][device]
            )
        self._interface = SpiDev()
        self._interface.open(port, device)
        self._interface.max_speed_hz = 500000

    def close(self):
        if getattr(self, '_interface', None):
            self._interface.close()
        self._interface = None
        self.pin_factory.release_all(self)
        super(LocalPiHardwareSPI, self).close()

    @property
    def closed(self):
        return self._interface is None

    def __repr__(self):
        try:
            self._check_open()
            return 'SPI(port=%d, device=%d)' % (self._port, self._device)
        except DeviceClosed:
            return 'SPI(closed)'

    def transfer(self, data):
        """
        Writes data (a list of integer words where each word is assumed to have
        :attr:`bits_per_word` bits or less) to the SPI interface, and reads an
        equivalent number of words, returning them as a list of integers.
        """
        return self._interface.xfer2(data)

    def _get_clock_mode(self):
        return self._interface.mode

    def _set_clock_mode(self, value):
        self._interface.mode = value

    def _get_lsb_first(self):
        return self._interface.lsbfirst

    def _set_lsb_first(self, value):
        self._interface.lsbfirst = bool(value)

    def _get_select_high(self):
        return self._interface.cshigh

    def _set_select_high(self, value):
        self._interface.cshigh = bool(value)

    def _get_bits_per_word(self):
        return self._interface.bits_per_word

    def _set_bits_per_word(self, value):
        self._interface.bits_per_word = value
コード例 #20
0
ファイル: sipmspi.py プロジェクト: jlabounty/beagle-code
class SipmSPI:
    def __init__(self, spinum, sipmpins, chippins):
        self.spi = SpiDev(spinum, 0)
        self.spi.mode = 3
        self.spi.max_speed_hz = 1000000

        self.sipmpins = ['P9_%i' % num for num in sipmpins]
        self.chippins = ['P9_%i' % num for num in chippins]
        for pin in self.sipmpins + self.chippins:
            GPIO.setup(pin, GPIO.OUT)
            GPIO.output(pin, GPIO.LOW)

    def select_sipm(self, sipm_number):
        for idx, pin_name in enumerate(self.sipmpins):
            if (sipm_number >> idx & 0x1):
                GPIO.output(pin_name, GPIO.HIGH)
            else:
                GPIO.output(pin_name, GPIO.LOW)
#print("sipm %d selected" % sipm_number)

    def chip_select(self, key):
        chip_num = CHIP_MAP[key]
        for idx, pin_name in enumerate(self.chippins):
            if (chip_num >> idx & 0x1):
                GPIO.output(pin_name, GPIO.HIGH)
            else:
                GPIO.output(pin_name, GPIO.LOW)

    def reset_temperature(self):
        self.spi.xfer2([0xff, 0xff, 0xff, 0xff])
        #self.spi.xfer2([0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
        #time.sleep(0.2)

        res = self.spi.xfer2([0x40, 0x00])  # read status register
        print("status: 0x%02x" % res[1])

        res = self.spi.xfer2([0x48, 0x00])  # read config register
        print("status: 0x%02x" % res[1])

        res = self.spi.xfer2([0x58, 0x00])  # read ID register
        print("status: 0x%02x" % res[1])

    def setup_temperature(self):
        self.spi.xfer2([0x08, 0x80])
#		time.sleep(0.2)

    def read_temperature(self):
        res = self.spi.xfer2([0x50, 0x00, 0x00])
        #temp = (res[1] << 5 | res[2] >> 3) / 16.0
        temp = (res[1] << 8 | res[2]) / 128.0
        #print("temp: %f deg C" % temp)
        return str(temp)

    def read_gain(self):
        res = self.spi.xfer2([0x83, 0x00])
        gain_read = res[1]
        #print("old gain readout: %d = %f dB" % (gain_read, 26 - gain_read / 4.0))
        return str(gain_read)

    def set_gain(self, gain_value):
        res = self.spi.xfer2([0x03, gain_value])
        res = self.spi.xfer2([0x83, 0x00])
        gain_read = res[1]
        return str(gain_read)

    def check_eeprom_status(self):
        res = self.spi.xfer2([0x05, 0x00])
        print("eeprom status 0x%02x\n" % res[1])

    def read_eeprom_page(self, page):
        page <<= 4
        cmd = [0x03, page] + [0 for i in range(16)]
        res = self.spi.xfer2(cmd)
        int_array = res[2:]
        #utf8 safety
        chr_array = [' ' if i == 255 else chr(i) for i in int_array]
        return ''.join(chr_array)

    def write_eeprom_page(self, page, msg):
        page <<= 4
        #enable write latch
        self.spi.xfer2([0x06])
        self.check_eeprom_status()
        #write page
        cmd = [0x02, page] + msg
        res = self.spi.xfer2(cmd)
        #		print(res)
        self.check_eeprom_status()
        return res
コード例 #21
0
class ADS1293:
    """SpiDev Wrapper for TI ADS1293
    """
    def __init__(self, bus=0, device=0):
        """initializes the SPI bus for the ADS1293
        """
        self.bus, self.device = bus, device
        self.spi = SpiDev()
        self.open()
        self.inax_max = [0, 0, 0]
        self.inax_min = [0, 0, 0]
        self.inax_zero = [0, 0, 0]

    def open(self):
        """opens the SPI bus for the ADS1293
        """
        self.spi.open(self.bus, self.device)
        self.spi.max_speed_hz = F_SCLK

    def close(self):
        self.spi.close()

    def read(self, register, num_bytes=1):
        """reads a number of bytes from the ADS1293
        """
        data = [0] * (num_bytes + 1)
        data[0] = READ_BIT | register
        self.spi.xfer2(data)
        return data[1:]

    def write(self, register, value):
        """writes the value value to register register
        """
        data = [WRITE_BIT & register, value]
        self.spi.xfer2(data)

    def go_to_standby(self):
        """sends the ADS1293 to standby
        """
        self.write(CONFIG, STANDBY)

    def test(self):
        # initial setup
        count = 100
        self.write(OSC_CN, 0x04)  # set external oscillator
        self.write(R2_RATE, 0x02)  # set R2 decimation rate as 5
        for i in range(3):  # for all three Channels
            # shut down unused circuitry
            shdn = 0
            for j in range(3):
                if i != j:
                    shdn = shdn | AFE_SHDN_INA_CHx[j] | AFE_SHDN_SDM_CHx[j]
            self.write(AFE_SHDN_CN, shdn)

            # initialize channel
            self.write(R3_RATE_CHx[i], 0x02)  # set R3 decimation rate as 6
            self.write(CH_CNFG, Ex_EN[i])  # enable loopback reading

            # positive test voltage
            self.write(FLEX_CHx_CN[i],
                       TST_POS)  # connect channel to pos test signal
            self.write(CONFIG, START_CON)  # start data conversion
            results = self.stat_values(count, Ex_DRDY[i])
            self.write(CONFIG, STANDBY)  # send chip to standby
            self.inax_max[i] = results[0]
            logging.info("Channel %d positive test:\n\t"
                         "Expected: %.1f\n\t"
                         "Received: %.1f avg [%.1f]\n\t\t"
                         "  (%.1f min, %.1f max, %.1f stddev)" %
                         (i + 1, ADC_OUT_POS, results[0], results[0] -
                          ADC_OUT_POS, results[1], results[2], results[3]))

            # negative test voltage
            self.write(FLEX_CHx_CN[i],
                       TST_NEG)  # connect channel to neg test signal
            self.write(CONFIG, START_CON)  # start data conversion
            results = self.stat_values(count, Ex_DRDY[i])
            self.write(CONFIG, STANDBY)  # send chip to standby
            self.inax_min[i] = results[0]
            logging.info("Channel %d negative test:\n\t"
                         "Expected: %.1f\n\t"
                         "Received: %.1f avg [%.1f]\n\t\t"
                         "  (%.1f min, %.1f max, %.1f stddev)" %
                         (i + 1, ADC_OUT_NEG, results[0], results[0] -
                          ADC_OUT_NEG, results[1], results[2], results[3]))

            # zero test voltage
            self.write(FLEX_CHx_CN[i], TST_ZER)
            self.write(CONFIG, START_CON)  # start data conversion
            results = self.stat_values(count, Ex_DRDY[i])
            self.write(CONFIG, STANDBY)  # send chip to standby
            self.inax_zero[i] = results[0]
            logging.info("Channel %d zero test:\n\t"
                         "Expected: %.1f\n\t"
                         "Received: %.1f avg [%.1f]\n\t\t"
                         "  (%.1f min, %.1f max, %.1f stddev)" %
                         (i + 1, ADC_OUT_ZERO, results[0], results[0] -
                          ADC_OUT_ZERO, results[1], results[2], results[3]))

            # deinitialize channel
            self.write(FLEX_CHx_CN[i], 0x00)  # disconnect the channel
            self.write(R3_RATE_CHx[i], 0x00)  # reset R3 decimation rate

        # reset the self
        self.reset()

    def reset(self):
        self.deinit_three_lead_ecg()
        self.deinit_five_lead_ecg()

    def check_ready(self, datareadybit=E1_DRDY):
        result = self.read(DATA_STATUS)
        return result[0] & datareadybit

    def stat_values(self, count=100, channel=E1_DRDY):
        """returns a list of avg, min, max, stdev
        """
        results = []
        i = 0
        while i < count:
            if self.check_ready(channel):
                data = self.read(DATA_LOOP, NUM_ECG_DATA_REGISTERS * 1)
                results.append(data[0] << 16 | data[1] << 8 | data[2])
                i += 1
        return [
            sum(results) / len(results),
            min(results),
            max(results),
            statistics.stdev(results)
        ]

    def init_three_lead_ecg(self):
        """Initializes the ADS1293 to the 3-Lead ECG application from the
        datasheet, chapter 9.2.1
        """
        # 1. Set address 0x01 = 0x11: Connect channel 1’s INP to IN2 and INN to IN1.
        self.write(FLEX_CH1_CN, POS_IN2 | NEG_IN1)
        # 2. Set address 0x02 = 0x19: Connect channel 2’s INP to IN3 and INN to IN1.
        self.write(FLEX_CH2_CN, POS_IN3 | NEG_IN1)
        # 3. Set address 0x0A = 0x07: Enable the common-mode detector on input pins
        # IN1, IN2 and IN3.
        self.write(CMDET_EN, 0x07)
        # 4. Set address 0x0C = 0x04: Connect the output of the RLD amplifier
        # internally to pin IN4.
        self.write(RLD_CN, 0x04)
        # 5. Set address 0x12 = 0x04: Use external crystal and feed the internal
        # oscillator's output to the digital.
        self.write(OSC_CN, 0x04)
        # 6. Set address 0x14 = 0x24: Shuts down unused channel 3’s signal path.
        self.write(AFE_SHDN_CN, 0x24)
        # 7. Set address 0x21 = 0x02: Configures the R2 decimation rate as 5 for all
        # channels.
        self.write(R2_RATE, 0x02)
        # 8. Set address 0x22 = 0x02: Configures the R3 decimation rate as 6 for
        # channel 1.
        self.write(R3_RATE_CH1, 0x02)
        # 9. Set address 0x23 = 0x02: Configures the R3 decimation rate as 6 for
        # channel 2.
        self.write(R3_RATE_CH2, 0x02)
        # 10. Set address 0x27 = 0x08: Configures the DRDYB source to channel 1 ECG
        # (or fastest channel).
        self.write(DRDYB_SRC, 0x08)
        # 11. Set address 0x2F = 0x30: Enables channel 1 ECG and channel 2 ECG for
        # loop read-back mode.
        self.write(CH_CNFG, 0x30)
        # 12. Set address 0x00 = 0x01: Starts data conversion.
        self.write(CONFIG, START_CON)

    def deinit_three_lead_ecg(self):
        """Deinitializes the ADS1293.
        Effectively this sends the ADS1293 to standby and sets the initialized
        registers to their default values.
        """
        # send ADS1293 to standby mode to save energy
        self.write(CONFIG, STANDBY)
        # reset registers to their default values
        self.write(CH_CNFG, 0x00)
        self.write(DRDYB_SRC, 0x00)
        self.write(R3_RATE_CH2, 0x00)
        self.write(R3_RATE_CH1, 0x00)
        self.write(R2_RATE, 0x00)
        self.write(AFE_SHDN_CN, 0x00)
        self.write(OSC_CN, 0x00)
        self.write(RLD_CN, 0x00)
        self.write(CMDET_EN, 0x00)
        self.write(FLEX_CH2_CN, 0x00)
        self.write(FLEX_CH1_CN, 0x00)

    def init_five_lead_ecg(self):
        """Initializes the ADS1293 to the 5-Lead ECG application from the
        datasheet, chapter 9.2.2
        """
        # 1. Set address 0x01 = 0x11: Connect channel 1’s INP to IN2 and INN to IN1.
        self.write(FLEX_CH1_CN, POS_IN2 | NEG_IN1)
        # 2. Set address 0x02 = 0x19: Connect channel 2’s INP to IN3 and INN to IN1.
        self.write(FLEX_CH2_CN, POS_IN3 | NEG_IN1)
        # 3. Set address 0x03 = 0x2E: Connect channel 3’s INP to IN5 and INN to IN6.
        self.write(FLEX_CH3_CN, POS_IN5 | NEG_IN6)
        # 4. Set address 0x0A = 0x07: Enable the common-mode detector on input pins IN1, IN2 and IN3.
        self.write(CMDET_EN, 0x07)
        # 5. Set address 0x0C = 0x04: Connect the output of the RLD amplifier internally to pin IN4.
        self.write(RLD_CN, 0x04)
        # 6. Set addresses 0x0D = 0x01, 0x0E = 0x02, 0x0F = 0x03: COnnects the first buffer of the Wilson reference to the IN1 pin, the second buffer to the IN2 pin, and the third buffer to the IN3 pin.
        self.write(WILSON_EN1, 0x01)
        self.write(WILSON_EN2, 0x02)
        self.write(WILSON_EN3, 0x03)
        # 7. Set address 0x10 = 0x01: Connects the output of the Wilson reference internally to IN6
        self.write(WILSON_CN, 0x01)
        # 8. Set address 0x12 = 0x04: Uses external crystal and feeds the output of the internal oscillator module to the digital.
        self.write(OSC_CN, 0x04)
        # 9. Set address 0x21 = 0x02: Configures the R2 decimation rate as 5 for all channels.
        self.write(R2_RATE, 0x02)
        # 10. Set address 0x22 = 0x02: Configures the R3 decimation rate as 6 for channel 1.
        self.write(R3_RATE_CH1, 0x02)
        # 11. Set address 0x23 = 0x02: Configures the R3 decimation rate as 6 for channel 2.
        self.write(R3_RATE_CH2, 0x02)
        # 12. Set address 0x24 = 0x02: Configures the R3 decimation rate as 6 for channel 3.
        self.write(R3_RATE_CH3, 0x02)
        # 12. Set address 0x27 = 0x08: Configures the DRDYB source to channel 1 ECG (or fastest channel).
        self.write(DRDYB_SRC, 0x08)
        # 11. Set address 0x2F = 0x70: Enables ECG channel 1, ECG channel 2 and ECG channel 3 for loop read-back mode.
        self.write(CH_CNFG, 0x70)
        # 12. Set address 0x00 = 0x01: Starts data conversion.
        self.write(CONFIG, START_CON)

    def deinit_five_lead_ecg(self):
        """Deinitializes the ADS1293.
        Effectively this sends the ADS1293 to standby and sets the initialized
        registers to their default values.
        """
        # send ADS1293 to standby mode to save energy
        self.write(CONFIG, STANDBY)
        # reset registers to their default values
        self.write(CH_CNFG, 0x00)
        self.write(DRDYB_SRC, 0x00)
        self.write(R3_RATE_CH3, 0x00)
        self.write(R3_RATE_CH2, 0x00)
        self.write(R3_RATE_CH1, 0x00)
        self.write(R2_RATE, 0x00)
        self.write(OSC_CN, 0x00)
        self.write(WILSON_CN, 0x00)
        self.write(WILSON_EN3, 0x00)
        self.write(WILSON_EN2, 0x00)
        self.write(WILSON_EN1, 0x00)
        self.write(RLD_CN, 0x00)
        self.write(CMDET_EN, 0x00)
        self.write(FLEX_CH3_CN, 0x00)
        self.write(FLEX_CH2_CN, 0x00)
        self.write(FLEX_CH1_CN, 0x00)
コード例 #22
0
ファイル: cc2500.py プロジェクト: onionys/pymaker
class cc2500:

    REG_MARCSTATE = 0xC0 | 0x35
    CMD_SRES = 0x30
    CMD_SFSTXON = 0x31
    CMD_SXOFF = 0x32
    CMD_XCAL = 0x33
    CMD_SRX  = 0x34
    CMD_STX  = 0x35
    CMD_SIDLE = 0x36
    CMD_SWOR = 0x38
    CMD_SPWD = 0x39
    CMD_SFRX = 0x3A
    CMD_SFTX = 0x3B
    CMD_SWORRST = 0x3C
    CMD_SNOP = 0x3D
    CMD_PATABLE = 0x3E
    CMD_TXFIFO = 0x3F

    CMD_SINGLE_WRITE = 0x00
    CMD_BRUST_WRITE = 0x40
    CMD_SINGLE_READ  = 0x80
    CMD_BRUST_READ = 0xC0



    # get Main Radio Control State Machine State
    def __init__(self, bus = 0, channel_select = 1):
        self.bus = SpiDev()
        self.bus.open(bus,channel_select)
        self.reset()
        self.buff=[]
        self.run = True
        self.timestamp = time()

    def get_STATE(self):
        return self.bus.xfer2([self.REG_MARCSTATE,0x00])[1]

    def set_reg(self,reg, byte):
        return self.bus.xfer2([reg, byte])

    def get_reg(self, reg):
        return self.bus.xfer2([0x80 | reg, 0x00])

    def info(self):
        state = self.get_STATE()
        txbyte = self.get_TXBYTES()
        rxbyte = self.get_RXBYTES()
        print "state : %d , tx: %d , rx: %d " % (state, txbyte, rxbyte)


    ## 
    ## COMMAND  
    ##
    def STX(self):
        return self.bus.xfer2([self.CMD_STX])

    def SRX(self):
        return self.bus.xfer2([self.CMD_SRX])

    def SIDLE(self):
        return self.bus.xfer2([self.CMD_SIDLE])

    def SFRX(self):
        return self.bus.xfer2([self.CMD_SFRX])
    
    def SFTX(self):
        return self.bus.xfer2([self.CMD_SFTX])

    def SRES(self):
        return self.bus.xfer2([self.CMD_SRES])

    def reset(self):
        self.SRES()
        reg_config = [0x0B, 0x2E, 0x06, 0x07, 0xD3, 0x91, 0x61, 0x04,
                      0x45, 0x00, 0x00, 0x09, 0x00, 0x5D, 0x93, 0xB1,
                      0x2D, 0x3B, 0x73, 0x22, 0xF8, 0x01, 0x07, 0x00,
                      0x18, 0x1D, 0x1C, 0xC7, 0x00, 0xB2, 0x87, 0x6B,
                      0xF8, 0xB6, 0x10, 0xEA, 0x0A, 0x00, 0x11, 0x41,
                      0x00, 0x59, 0x7F, 0x3F, 0x88, 0x31, 0x0B ]
        for reg, val in enumerate(reg_config):
            self.bus.xfer2([reg, val])
        self.SIDLE()
        self.SFRX()
        self.SFTX()



    ## FIFO buffer 64byte
    def send(self,package):
        tmp = []
        if type(package) == str:
            tmp = [ord(i) for i in package]
        else:
            tmp = list(package)
        tmp = [self.CMD_TXFIFO | self.CMD_BRUST_WRITE ,len(tmp)] + tmp
        print "send"
        print tmp
        self.bus.xfer2(tmp)    # write package to fifo buffer (max 64byte)
        if self.get_STATE() == 22:
            self.SFTX()
            self.SIDLE()
            return -1
        self.STX()
        return 0

    def get_package_RXFIFO(self):
        len_FIFO = self.get_RXBYTES()
        p_len = self.get_byte_RXFIFO()
        data = self.bus.xfer2([self.CMD_BRUST_READ | 0x3F for i in range(len_FIFO)])
        self.buff.append(data)
            
    def get_byte_RXFIFO(self):
        return self.bus.xfer2( [ self.CMD_SINGLE_READ | 0x3F , 0x00])[1]

    def set_byte_TXFIFO(self, byte):
        return self.bus.xfer2( [ self.CMD_SINGLE_WRITE | 0x3F , byte])[1]

    def get_TXBYTES(self):
        return self.bus.xfer2([0xC0 | 0x3A, 0x00])[1]

    def get_RXBYTES(self):
        return self.bus.xfer2([0xC0 | 0x3B, 0x00])[1]

    def stop(self):
        self.run = False

    def start(self):
        self.thread = Thread(target=self.receive_loop, args=())
        self.run = True
        self.thread.start()

    def receive_loop(self):
        while self.run :
            state = self.get_STATE()
            rxbytes = self.get_RXBYTES()
            txbytes = self.get_TXBYTES()

            if(state in [13,8,9,10,11]):
                #print state
                sleep(0.1)
                continue

            elif( (state == 1) and (rxbytes > 0)):
                #print state
                self.get_package_RXFIFO()
                self.SRX()

            elif(state == 1):
                #print state
                self.SIDLE()
                self.SRX()

            elif(state == 17):
                #print state
                self.SFRX()
                self.SIDLE()
                self.SRX()

            else:
                #print state
                self.reset()
                sleep(0.1)

            if time() > (self.timestamp + 10 ):
                print "reset"
                self.timestamp = time()
                self.reset()

            sleep(0.1)
            if len(self.buff) > 0:
                data = self.buff.pop(0)[1:-2]
                msg = ''.join([chr(i) for i in data])
                print(msg)
コード例 #23
0
ファイル: cc2500.py プロジェクト: onionys/python_code
class CC2500(object):

    REG_MARCSTATE = 0xC0 | 0x35
    CMD_SRES = 0x30
    CMD_SFSTXON = 0x31
    CMD_SXOFF = 0x32
    CMD_XCAL = 0x33
    CMD_SRX  = 0x34
    CMD_STX  = 0x35
    CMD_SIDLE = 0x36
    CMD_SWOR = 0x38
    CMD_SPWD = 0x39
    CMD_SFRX = 0x3A
    CMD_SFTX = 0x3B
    CMD_SWORRST = 0x3C
    CMD_SNOP = 0x3D
    CMD_PATABLE = 0x3E
    CMD_TXFIFO = 0x3F

    CMD_SINGLE_WRITE = 0x00
    CMD_BRUST_WRITE = 0x40
    CMD_SINGLE_READ  = 0x80
    CMD_BRUST_READ = 0xC0

    # get Main Radio Control State Machine State
    def __init__(self, bus = 0, channel_select = 1):
        self.bus = SpiDev()
        self.bus.open(bus,channel_select)
        self.reset()

    ## 
    ## COMMAND  
    ##
    def STX(self):
        self.bus.xfer2([self.CMD_STX])

    def SRX(self):
        self.bus.xfer2([self.CMD_SRX])

    def SIDLE(self):
        self.bus.xfer2([self.CMD_SIDLE])

    def SFRX(self):
        self.bus.xfer2([self.CMD_SFRX])
    
    def SFTX(self):
        self.bus.xfer2([self.CMD_SFTX])

    def SRES(self):
        self.bus.xfer2([self.CMD_SRES])

    ## Access REG

    def get_STATE(self):
        return self.bus.xfer2([0xC0 | 0x35, 0x00])[1]

    def get_RXBYTES(self):
        return self.bus.xfer2([0xC0 | 0x3B, 0x00])[1]


    def write_TXFIFO(self,package):
        tmp = []
        if type(package) == str:
            tmp = [ord(i) for i in package]
        else:
            tmp = list(package)
        tmp = [self.CMD_TXFIFO | self.CMD_BRUST_WRITE ,len(tmp)] + tmp
        self.bus.xfer2(tmp)    # write package to fifo buffer (max 64byte)


    def read_RXFIFO(self):
        len_FIFO = self.get_RXBYTES()
        return self.bus.xfer2([self.CMD_BRUST_READ | 0x3F for i in range(len_FIFO)])


    def reset(self):
        self.SRES()

        reg_config = [
            0x29,0x2E,0x06,0x07,0xD3,0x91,0x61,0x04,
            0x45,0x00,0x00,0x09,0x00,0x5E,0xC4,0xEC,
            0x2C,0x22,0x73,0x22,0xF8,0x01,0x07,0x00,
            0x18,0x1D,0x1C,0xC7,0x00,0xB2,0x87,0x6B,
            0xF8,0xB6,0x10,0xEB,0x0B,0x1D,0x11,0x41,
            0x00,0x59,0x7F,0x3C,0x88,0x31,0x0B
        ]

        for reg, val in enumerate(reg_config):
            self.bus.xfer2([reg, val])

        self.SIDLE()
        self.SFRX()
        self.SFTX()

    def read_config(self):
        reg_config = []
        for reg in range(49):
            val = self.bus.xfer2([0x80 | reg , 0x00])[1]
            reg_config.append(val)
        return reg_config
    ## USER API

    def write(self,package):
        self.write_TXFIFO(package)
        if(self.get_STATE() == 22):
            self.SFTX()
            self.SIDLE()
            return -1
        self.STX()
        return 0

    def read(self):
        self.reset()
        self.SRX()
        while(True):
            sleep(0.1)
            state = self.get_STATE()
            if(state in [13,14,15]):
                continue
            elif(state == 1):
                res = self.read_RXFIFO()
                return res
            elif(state == 17):
                self.SFRX()
                self.SIDLE()
                return -1
コード例 #24
0
class AMIS30543_Controller():
    def __init__(self, DO_DIRECTION_PIN, DO_RESET_PIN, DI_FAULT_PIN, ARGS):

        self.REG = {  # AMIS-30543 Registers
            'WR': 0x00,
            'CR0': 0x01,
            'CR1': 0x02,
            'CR2': 0x03,
            'CR3': 0x09,
            'SR0': 0x04,
            'SR1': 0x05,
            'SR2': 0x06,
            'SR3': 0x07,
            'SR4': 0x0A
        }

        self.CMD = {  # AMIS-30543 Command constants
            'READ': 0x00,
            'WRITE': 0x80
        }

        self.dirctrl = ARGS[0]
        self.pwmf = ARGS[1]
        self.pwmj = ARGS[2]
        self.sm = ARGS[3]
        self.mult = ARGS[4]
        self.dist = ARGS[5]
        self.step = ARGS[6]

        self.VAL = {
            'WR': 0b00000000,  # no watchdog
            'CR0': 0b00010111 | self.sm,  # & 2.7 A current limit
            'CR1': 0b00000000 | self.dirctrl | self.pwmf
            | self.pwmj,  # & step on rising edge & fast slopes
            'CR2':
            0b00000000,  # motor off & no sleep & SLA gain @ 0.5 & SLA no transparent
            'CR3':
            0b00000000  #,                                         # no extended step mode
            #'dist': self.dist,
            #'step': self.step
        }

        # InitGPIO

        PWM.setup(5, 0)  # 5 us pulse_incr, 0 delay_hw
        PWM.init_channel(0, 3000)  # DMA channel 0, 3000 us subcycle time

        self.DO_RESET = gpiozero.DigitalOutputDevice(DO_RESET_PIN)
        self.DO_DIRECTION = gpiozero.DigitalOutputDevice(DO_DIRECTION_PIN)
        self.DI_NO_FAULT = gpiozero.DigitalInputDevice(DI_FAULT_PIN)

        self.spi = SpiDev()
        self.spi.open(0, 0)
        self.spi.max_speed_hz = 1000000

        self.RegisterSet()

    def __del__(self):
        self.spi.close()

    def ResetStepper(self):
        self.DO_RESET.off()  # must be off for AMIS to see reset
        time.sleep(0.11)
        self.DO_RESET.on()
        time.sleep(0.11)
        self.DO_RESET.off()

    def RegisterDump(self):  # to check stepper status
        print("\nAMIS-30543 Registers:")
        resp = self.spi.xfer2([self.CMD['READ'] | self.REG['WR'], 0])
        print(" WR = ", bin(resp[1]), " ", str(resp[1]))
        resp = self.spi.xfer2([self.CMD['READ'] | self.REG['CR0'], 0])
        print("CR0 = ", bin(resp[1]), " ", str(resp[1]))
        resp = self.spi.xfer2([self.CMD['READ'] | self.REG['CR1'], 0])
        print("CR1 = ", bin(resp[1]), " ", str(resp[1]))
        resp = self.spi.xfer2([self.CMD['READ'] | self.REG['CR2'], 0])
        print("CR2 = ", bin(resp[1]), " ", str(resp[1]))
        resp = self.spi.xfer2([self.CMD['READ'] | self.REG['CR3'], 0])
        print("CR3 = ", bin(resp[1]), " ", str(resp[1]))
        resp = self.spi.xfer2([self.CMD['READ'] | self.REG['SR0'], 0])
        print("SR0 = ", bin(resp[1]), " ", str(resp[1]))
        resp = self.spi.xfer2([self.CMD['READ'] | self.REG['SR1'], 0])
        print("SR1 = ", bin(resp[1]), " ", str(resp[1]))
        resp = self.spi.xfer2([self.CMD['READ'] | self.REG['SR2'], 0])
        print("SR2 = ", bin(resp[1]), " ", str(resp[1]))
        resp = self.spi.xfer2([self.CMD['READ'] | self.REG['SR3'], 0])
        print("SR3 = ", bin(resp[1]), " ", str(resp[1]))
        resp = self.spi.xfer2([self.CMD['READ'] | self.REG['SR4'], 0])
        print("SR4 = ", bin(resp[1]), " ", str(resp[1]))
        print("")

    def RegisterSet(self):
        self.ResetStepper()

        self.spi.writebytes(
            [self.CMD['WRITE'] | self.REG['WR'], self.VAL['WR']])
        self.spi.writebytes(
            [self.CMD['WRITE'] | self.REG['CR0'], self.VAL['CR0']])
        self.spi.writebytes(
            [self.CMD['WRITE'] | self.REG['CR1'], self.VAL['CR1']])
        self.spi.writebytes(
            [self.CMD['WRITE'] | self.REG['CR2'], self.VAL['CR2']])
        self.spi.writebytes(
            [self.CMD['WRITE'] | self.REG['CR3'], self.VAL['CR3']])

        if self.spi.xfer2([self.CMD['READ'] | self.REG['WR'], 0
                           ])[1] != self.VAL['WR']:
            print(
                "Writing or reading self.REG['WR'] failed; driver power might be off."
            )
            return False
        if self.spi.xfer2([self.CMD['READ'] | self.REG['CR0'], 0
                           ])[1] != self.VAL['CR0']:
            print(
                "Writing or reading self.REG['CR0'] failed; driver power might be off."
            )
            return False
        if self.spi.xfer2([self.CMD['READ'] | self.REG['CR1'], 0
                           ])[1] != self.VAL['CR1']:
            print(
                "Writing or reading self.REG['CR1'] failed; driver power might be off."
            )
            return False
        if self.spi.xfer2([self.CMD['READ'] | self.REG['CR2'], 0
                           ])[1] != self.VAL['CR2']:
            print(
                "Writing or reading self.REG['CR2'] failed; driver power might be off."
            )
            return False
        if self.spi.xfer2([self.CMD['READ'] | self.REG['CR3'], 0
                           ])[1] != self.VAL['CR3']:
            print(
                "Writing or reading self.REG['CR3'] failed; driver power might be off."
            )
            return False

        #self.RegisterDump()
        #print("RegisterSet Ok\n")
        return True

    def SetMotorEnable(self):

        self.spi.writebytes([
            self.CMD['WRITE'] | self.REG['CR2'], self.VAL['CR2'] | 0b10000000
        ])

        if self.spi.xfer2([self.CMD['READ'] | self.REG['CR2'], 0
                           ])[1] != self.VAL['CR2'] | 0b10000000:
            print(
                "Writing or reading self.REG['CR2'] failed; driver power might be off."
            )
            return False

    def SetMotorDisable(self):

        self.spi.writebytes([
            self.CMD['WRITE'] | self.REG['CR2'], self.VAL['CR2'] & 0b01111111
        ])

        if self.spi.xfer2([self.CMD['READ'] | self.REG['CR2'], 0
                           ])[1] != self.VAL['CR2'] & 0b01111111:
            print(
                "Writing or reading self.REG['CR2'] failed; driver power might be off."
            )
            return False
コード例 #25
0
ファイル: energy.py プロジェクト: abuehner/deepRacin-on-FPGAs
from spidev import SpiDev
import RPi.GPIO as GPIO           # import RPi.GPIO module  
GPIO.setmode(GPIO.BOARD)            # choose BCM or BOARD  
GPIO.setup(11, GPIO.OUT) # set a port/pin as an output   

channel = 0
bus = 0

bus, device = bus, device
spi = SpiDev()
spi.open(bus, device

# xfer2(list of values[, speed_hz, delay_usec, bits_per_word])
	#s
adc = spi.xfer2([1, (8 + channel) << 4, 0])

voltages = []
powerSum = 0


GPIO.output(11, 1)       # set port/pin value to 1/GPIO.HIGH/True  


for i in range(0, 10):
   if (i == 8):
      GPIO.output(11,0)
   voltages[i] = ((adc[1] & 3) << 8) + adc[2]
   power = math.pow(voltages[i]/1023.0 * 3.3, 2)* ((voltages[i]/1023.0 * 3.3)/100
   powerSum += power
   print("power: %.2f" % power)
コード例 #26
0
class SPIHandler:

    def __init__(self, state_instance):
        self._shutdown_ctr = Counter(2)

        PTLogger.debug("\t\tCreating SPI handler")
        self._state = state_instance
        self.spi = None
        PTLogger.debug("\t\t\tSetting up SPI")
        self._setup_spi()
        PTLogger.debug("\t\t\tGetting initial state data")
        self._get_state_from_hub(init=True)

        init_state = StateChange(SPIStateChangeType.init, True)
        self.queued_changes = [init_state]

    def _update_state_from_pending_state_change(self, state_change_to_send):

        # If state is to change, update appropriate bit(s)
        if state_change_to_send is not None:

            if state_change_to_send._type == SPIStateChangeType.screen:
                if state_change_to_send._operation == SPIScreenOperations.blank:
                    self._state.set_screen_blanked()
                elif state_change_to_send._operation == SPIScreenOperations.unblank:
                    self._state.set_screen_unblanked()
                else:
                    msg = "Unrecognised screen state change"
                    msg += " - unable to parse into bits. Ignoring..."
                    PTLogger.info(msg)

            elif state_change_to_send._type == SPIStateChangeType.brightness:

                if _represents_int(state_change_to_send._operation):
                    brightness_level = int(state_change_to_send._operation)
                    if brightness_level >= 0 and brightness_level <= 10:
                        self._state.set_brightness(brightness_level)

    def transceive_and_process(self):
        state_change_to_send = self.pop_from_queue()
        self._update_state_from_pending_state_change(state_change_to_send)  # Should this be here?

        # Set bits to send according to state variables
        if state_change_to_send is not None:
            # Pi's current state
            bits_to_send = self._parse_state_to_bits()
        else:
            # Probe for hub's state
            bits_to_send = 255

        hub_response_bstring = self._transceive_spi(bits_to_send)
        byte_type = self._determine_byte(hub_response_bstring)

        # Determine if received byte represents device ID or state
        if byte_type == SPIResponseType.device_id:

            PTLogger.debug("Valid response from hub - DEVICE ID")
            self._process_device_id(hub_response_bstring)

        elif byte_type == SPIResponseType.state:

            self._process_spi_resp(hub_response_bstring)

            # State update has been sent to hub: perform another transceive to sync states
            self._get_state_from_hub(process_state=False)

        else:

            PTLogger.warning("Invalid response from hub")
            return False

        return True

    def pop_from_queue(self):
        if len(self.queued_changes) > 0:
            state_change_to_send = self.queued_changes[0]
            self.queued_changes.remove(self.queued_changes[0])
        else:
            state_change_to_send = None

        return state_change_to_send

    def _process_device_id(self, resp):
        device_id = resp[5:8]

        if device_id == "000":
            PTLogger.info("Hub reports it's a pi-top v1")
            self._state.set_device_id(DeviceID.pi_top)
        elif device_id == "001":
            PTLogger.info("Hub reports it's a CEED")
            self._state.set_device_id(DeviceID.pi_top_ceed)

    def _parity_of(self, int_type):
        '''
        Calculates the parity of an integer,
        returning 0 if there are an even number of set bits,
        and 1 if there are an odd number
        '''
        parity = 0
        for bit in bin(int_type)[2:]:
            parity ^= int(bit)
        return parity

    def _parse_state_to_bits(self):
        br_parity_bits = str(self._parity_of(self._state._brightness))
        scaled_screen_off = (2 * int(self._state._screen_blanked))
        state_bits_val = scaled_screen_off + self._state._shutdown
        state_parity_bits = str(self._parity_of(state_bits_val))

        # Determine new bits to send
        # bs = bitshifted
        # br = brightness
        # par = parity
        bs_br_par = (128 * int(br_parity_bits))
        bs_br = (8 * self._state._brightness)
        bs_state_par = (4 * int(state_parity_bits))
        bs_screen_off = (2 * int(self._state._screen_blanked))
        bits_to_send = bs_br_par
        bits_to_send += bs_br
        bits_to_send += bs_state_par
        bits_to_send += bs_screen_off
        bits_to_send += self._state._shutdown
        # e.g. bits = "10101010"
        # brightness parity = 1
        # brightness = 5
        # state parity = 0
        # screen_off = 1
        # shutdown = 0

        return bits_to_send

    def _setup_spi(self):
        if self.spi is None:
            from spidev import SpiDev
            self.spi = SpiDev()
            self.spi.open(0, 1)
            self.spi.max_speed_hz = 9600
            self.spi.mode = 0b00
            self.spi.bits_per_word = 8
            self.spi.cshigh = True
            self.spi.lsbfirst = False

    def _determine_byte(self, resp):
        # Check parity bit
        parity_bit_brightness = resp[0]
        brightness = resp[1:5]

        if parity_bit_brightness == "0" and brightness == "1111":
            return SPIResponseType.device_id
        else:
            correct_parity_val = str(self._parity_of(int(resp[1:8], 2)))

            if parity_bit_brightness != correct_parity_val:
                PTLogger.info("Invalid parity bit")
                return SPIResponseType.invalid

            return SPIResponseType.state

    def _process_spi_resp_shutdown(self, spi_shutdown_bit_int):
        if spi_shutdown_bit_int == 1:

            # Increment shutdown counter
            self._shutdown_ctr.increment()

            PTLogger.info("Received shutdown indication from hub (" + str(self._shutdown_ctr.current) + " of " + str(self._shutdown_ctr.max) + ")")

            if self._shutdown_ctr.maxed():
                self._shutdown_ctr.reset()
                self._state.set_shutdown(1)

        else:
            self._shutdown_ctr.reset()

    def _process_spi_resp(self, resp, init=False):

        # Message from hub bits:

        # 0     : check sum: set if odd number of set bits in rest of message
        # 1 - 4 : Brightness of screen backlight
        # 5     : Lid state, 1 if open, 0 if closed
        # 6     : Screen blank state, 0 if unblanked, 1 if blanked
        # 7     : Shutdown requested from hub, 1 if shutting down

        # If we're communicating, but we still haven't decided what device
        # we're on, then we must be on a CEED, as if we were on a pi-top v1,
        # we would have identified this via connecting to the battery on i2c.

        if int(resp) != 0 and self._state._device_id == DeviceID.unknown:
            PTLogger.info("Received comms from hub - assuming we're on a CEED")
            self._state.set_device_id(DeviceID.pi_top_ceed)

        # Check shutdown bit

        spi_shutdown_bit_int = int(resp[7])
        self._process_spi_resp_shutdown(spi_shutdown_bit_int)

        spi_screen_off_state = int(resp[6])
        if (spi_screen_off_state == 1):
            self._state.set_screen_blanked()
        else:
            self._state.set_screen_unblanked()

        spi_lid_state = int(resp[5])
        if (spi_lid_state == 1):
            self._state.set_lid_open()
        else:
            self._state.set_lid_closed()

        spi_brightness_int = int(resp[1:5], 2)
        screen_is_blanked = (spi_screen_off_state == 1 and spi_brightness_int == 0)
        if init or not screen_is_blanked:
            self._state.set_brightness(spi_brightness_int, False)

    def _transceive_spi(self, bits_to_send):
        hex_str_to_send = '0x' + str(hex(bits_to_send))[2:].zfill(2)
        bin_str_to_send = '{0:b}'.format(int(hex_str_to_send[2:], 16)).zfill(8)

        log_brightness = str(int(bin_str_to_send[1:5], 2))
        log_screen = "On" if bin_str_to_send[6] == "0" else "Off"
        log_shutdown = "Shutting down" if bin_str_to_send[7] == "1" else "No shutdown"

        if (bin_str_to_send == "11111111"):
            PTLogger.debug("Pi sending:   " + bin_str_to_send + " [ fetch state from hub ]")
        else:
            PTLogger.debug("Pi sending:   " + bin_str_to_send + " [" + log_brightness + ", " + log_screen + ", " + log_shutdown + "]")

        # Initiate receiving communication from hub
        self.spi.cshigh = False
        # Transfer data with hub
        resp = self.spi.xfer2([bits_to_send], self.spi.max_speed_hz)
        self.spi.cshigh = True

        resp_hex = hex(resp[0])
        resp_hex_str = '0x' + str(resp_hex)[2:].zfill(2)
        resp_bin_str = '{0:b}'.format(int(resp_hex_str[2:], 16)).zfill(8)

        log_brightness = str(int(resp_bin_str[1:5], 2))
        log_lid = "Open" if resp_bin_str[5] == "1" else "Closed"
        log_screen = "On" if resp_bin_str[6] == "0" else "Off"
        log_shutdown = "Shutting down" if resp_bin_str[7] == "1" else "No shutdown"

        PTLogger.debug("Hub responds: " + resp_bin_str + " [" + log_brightness + ", " + log_lid + ", " + log_screen + ", " + log_shutdown + "]")

        return resp_bin_str

    def _attempt_get_state(self):
        # Send 0xFF to get data from hub
        resp_bin_str = self._transceive_spi(255)

        byte_type = self._determine_byte(resp_bin_str)

        if byte_type == SPIResponseType.state:
            PTLogger.debug("Valid response from hub - STATE")
            valid = True
        else:
            if byte_type == SPIResponseType.device_id:
                PTLogger.debug("Valid response from hub - DEVICE ID")
                # Process SPI resp, store brightness signal for check next loop
                self._process_device_id(resp_bin_str)
            else:
                PTLogger.debug("Invalid response from hub")
            valid = False

        return valid, resp_bin_str

    def _get_state_from_hub(self, init=False, process_state=True):

        valid = False
        get_state_ctr = Counter(5)

        do_extra_read = init

        while not valid and not get_state_ctr.maxed():
            valid, resp_bin_str = self._attempt_get_state()

            if do_extra_read and valid:
                valid = False
                do_extra_read = False

            if not valid:
                get_state_ctr.current += 1
                sleep(_cycle_sleep_time)

        if valid:
            if process_state:
                self._process_spi_resp(resp_bin_str, init=init)
        else:
            PTLogger.error("Unable to communicate with hub. " + "init: " + str(init) + ", resp_bin_str: " + str(resp_bin_str))

        return valid
コード例 #27
0
ファイル: mcp2515.py プロジェクト: purduerov/X13_Embedded
class MCP2515():

	DEFAULT_SPI_CLOCK_FREQUENCY = 4000000 # 4MHz
	DEFAULT_CLOCK_POLARITY = 0
	DEFAULT_CLOCK_PHASE = 0

	# SPI Command Bytes
	RESET_INSTRUCTION_BYTE = 0xC0
	WRITE_INSTRUCTION_BYTE = 0x02
	READ_INSTRUCTION_BYTE = 0x03
	LOAD_TX_BUFFER_INSTRUCTION_BASE_BYTE = 0x40
	READ_RX_BUFFER_INSTRUCTION_BASE_BYTE = 0x90
	REQUEST_TO_SEND_INSTRUCTION_BYTE = 0x80
	READ_STATUS_INSTRUCTION_BYTE = 0xA0
	BIT_MODIFY_INSTRUCTION_BYTE = 0x05

	# CAN RX Filter Number to Address Map
	CAN_BUFFER_NUMBER_TO_CR_ADDRESS = [0x60, 0x70]
	CAN_FILTER_NUMBER_TO_STARTING_ADDRESS = [
		0x00,
		0x04,
		0x08,
		0x10,
		0x14,
		0x18
	]
	CAN_MASK_NUMBER_TO_STARTING_ADDRESS = [0x20, 0x24]

	BYTE_MASK = 0xFF

	def __init__(self, bus_num, device_num, 
			max_speed_hz=DEFAULT_SPI_CLOCK_FREQUENCY,
			clock_polarity=DEFAULT_CLOCK_POLARITY,
			clock_phase=DEFAULT_CLOCK_PHASE):

		self.spi_instance = SpiDev()

		self.bus_num = bus_num
		self.device_num = device_num

		self.clk_speed = max_speed_hz
		self.clk_polarity = clock_polarity
		self.clk_phase = clock_phase

	def set_spi_max_speed_hz(self, max_speed_hz=DEFAULT_SPI_CLOCK_FREQUENCY):
		self.spi_instance.max_speed_hz = max_speed_hz

	def set_spi_mode(self, clock_polarity=DEFAULT_CLOCK_POLARITY, clock_phase=DEFAULT_CLOCK_PHASE):
		self.spi_instance.mode = (clock_polarity << 1) | clock_phase

	def open_can_connection(self):
		self.spi_instance.open(self.bus_num, self.device_num)
		
		# Cannot set these SPI parameters until SPI connection has been opened
		self.set_spi_max_speed_hz(self.clk_speed)
		self.set_spi_mode(self.clk_polarity, self.clk_phase)

	def close_can_connection(self):
		self.spi_instance.close()

	def write_bytes(self, address, data_bytes):
		if not isinstance(data_bytes, list):
			data_bytes = [data_bytes]
		bytes_to_write = [MCP2515.WRITE_INSTRUCTION_BYTE, address];
		bytes_to_write.extend(data_bytes)
		self.spi_instance.xfer2(bytes_to_write)

	def read_bytes(self, address, num_bytes):
		bytes_to_write = [MCP2515.READ_INSTRUCTION_BYTE, address]
		bytes_to_write.extend([0] * num_bytes)
		bytes_read = self.spi_instance.xfer2(bytes_to_write)
		return bytes_read[2:]

	def reset(self):
		self.spi_instance.xfer2([MCP2515.RESET_INSTRUCTION_BYTE])

	def load_tx_buffer(self, can_message_buffer, can_message_buffer_number):
		data_bytes_to_send = []

		load_tx_buffer_command = MCP2515.LOAD_TX_BUFFER_INSTRUCTION_BASE_BYTE | (can_message_buffer_number << 1)
		data_bytes_to_send.append(load_tx_buffer_command)

		data_byte = (can_message_buffer.get_standard_id() & (MCP2515.BYTE_MASK << 3)) >> 3
		data_bytes_to_send.append(data_byte)

		data_byte = (can_message_buffer.get_standard_id() & 0x7) << 5
		data_byte |= (can_message_buffer.get_id_extension() << 3)

		if (can_message_buffer.get_id_extension()):
			data_byte |= ((can_message_buffer.get_extended_id() & (0x3 << 16)) >> 16)
			data_bytes_to_send.append(data_byte)

			data_byte = (can_message_buffer.get_extended_id() & (MCP2515.BYTE_MASK  << 8)) >> 8
			data_bytes_to_send.append(data_byte)

			data_byte = (can_message_buffer.get_extended_id() & MCP2515.BYTE_MASK)
			data_bytes_to_send.append(data_byte)
		else:
			data_bytes_to_send.append(data_byte)
			data_bytes_to_send.append(0x00)
			data_bytes_to_send.append(0x00)

		data_byte = can_message_buffer.get_remote_transmission() << 6
		data_byte |= can_message_buffer.get_num_data_bytes()
		data_bytes_to_send.append(data_byte)

		for i in range(can_message_buffer.get_num_data_bytes()):
			data_bytes_to_send.append(can_message_buffer.get_data_bytes()[i])

		self.spi_instance.xfer2(data_bytes_to_send)

	def send_tx_buffers(self, buffer0=False, buffer1=False, buffer2=False):
		buffer_bits = 0
		if buffer0: buffer_bits += 1
		if buffer1: buffer_bits += 2
		if buffer2: buffer_bits += 4
		byte_to_send = MCP2515.REQUEST_TO_SEND_INSTRUCTION_BYTE | buffer_bits
		print(f"RTS Byte = {byte_to_send}")
		self.spi_instance.xfer2([byte_to_send])

	def send_tx_buffer_with_priority(self, buffer_number, priority):
		# Priority [0, 3] with 0 the lowest and 3 the highest
		write_address = self.get_tx_buffer_control_register_address(buffer_number)
		data_byte_to_send = (1 << 3) | priority
		self.write_bytes(write_address, data_byte_to_send)

	def get_tx_buffer_control_register_address(self, buffer_number):
		BASE_TX_BUFFER_ADDRESS = 0x30
		NUM_BYTES_BETWEEN_TX_BUFFERS = 16
		return (BASE_TX_BUFFER_ADDRESS + (buffer_number * NUM_BYTES_BETWEEN_TX_BUFFERS))

	def get_status(self, num_consecutive_times=1):
		bytes_to_write = [MCP2515.READ_STATUS_INSTRUCTION_BYTE]
		bytes_to_write.extend([0] * num_consecutive_times)
		bytes_read = self.spi_instance.xfer2(bytes_to_write)
		return bytes_read[1:]

	def wait_until_tx_message_success(self, buffer_number):
		tx_message_success = False
		while (not tx_message_success):
			byte_read = self.get_status()[0]
			bit_mask = 1 << ((2 * buffer_number) + 2)
			tx_message_success = not (byte_read & bit_mask)
		return tx_message_success

	def configure_bit_timing(self, bit_timing_configuration):
		CONFIGURATION_REGISTER1_ADDRESS = 0x2A
		CONFIGURATION_REGISTER2_ADDRESS = 0x29
		CONFIGURATION_REGISTER3_ADDRESS = 0x28
		bytes_to_write = []
		
		byte_to_write = bit_timing_configuration.get_phase_segment2_length() & 0x07
		bytes_to_write.append(byte_to_write)

		byte_to_write = bit_timing_configuration.get_propagation_segment_length() & 0x07
		byte_to_write |= ((bit_timing_configuration.get_phase_segment1_length() & 0x07) << 3)
		if (bit_timing_configuration.get_num_samples_per_bit() == 3):
			byte_to_write |= (1 << 6)
		byte_to_write |= (1 << 7)
		bytes_to_write.append(byte_to_write)

		byte_to_write = bit_timing_configuration.get_baud_rate_prescalar() & 0x3F
		byte_to_write |= (bit_timing_configuration.get_sjw() - 1) & 0x03
		bytes_to_write.append(byte_to_write)

		self.write_bytes(CONFIGURATION_REGISTER3_ADDRESS, bytes_to_write)

	def switch_operation_modes(self, operating_mode):
		CAN_CONTROL_REGISTER_ADDRESS = 0x0F
		self.write_bytes(CAN_CONTROL_REGISTER_ADDRESS, operating_mode)

	def get_operation_mode(self):
		CAN_STATUS_REGISTER_ADDRESS = 0x0E
		read_byte = self.read_bytes(CAN_STATUS_REGISTER_ADDRESS, 1)[0]
		return OperationModes((read_byte & (0x7 << 5)) >> 5)

	def initialize(self, bit_timing_configuration):
		self.reset()
		time.sleep(.1)
		while (self.get_operation_mode() != OperationModes.CONFIGURATION):
			self.reset()
			time.sleep(.1)
		self.configure_bit_timing(bit_timing_configuration)
		while (self.get_operation_mode() != OperationModes.NORMAL):
			self.switch_operation_modes(OperationModes.NORMAL)
			time.sleep(.1)

	def set_can_rx_filter(self, can_filter_number, can_filter):
		# Filter Number = [0, 5]
		data_bytes_to_send = []
		base_filter_address = MCP2515.CAN_FILTER_NUMBER_TO_STARTING_ADDRESS[can_filter_number]

		data_byte = (can_filter.get_standard_id() & (MCP2515.BYTE_MASK << 3)) >> 3
		data_bytes_to_send.append(data_byte)

		data_byte = (can_filter.get_standard_id() & 0x7) << 5
		data_byte |= (can_filter.get_id_extension() << 3)

		if (can_filter.get_id_extension()):
			data_byte |= ((can_filter.get_extended_id() & (0x3 << 16)) >> 16)
			data_bytes_to_send.append(data_byte)

			data_byte = (can_filter.get_extended_id() & (MCP2515.BYTE_MASK  << 8)) >> 8
			data_bytes_to_send.append(data_byte)

			data_byte = (can_filter.get_extended_id() & MCP2515.BYTE_MASK)
			data_bytes_to_send.append(data_byte)
		else:
			data_bytes_to_send.append(data_byte)

			data_byte = (can_filter.get_data_byte0() & MCP2515.BYTE_MASK)
			data_bytes_to_send.append(data_byte)

			data_byte = (can_filter.get_data_byte1() & MCP2515.BYTE_MASK)
			data_bytes_to_send.append(data_byte)

		self.write_bytes(base_filter_address, data_bytes_to_send)

	def set_can_rx_mask(self, can_mask_number, can_mask):
		# Mask Number = [0, 1]
		data_bytes_to_send = []
		base_mask_address = MCP2515.CAN_MASK_NUMBER_TO_STARTING_ADDRESS[can_mask_number]

		data_byte = (can_mask.get_standard_id() & (MCP2515.BYTE_MASK << 3)) >> 3
		data_bytes_to_send.append(data_byte)

		data_byte = (can_mask.get_standard_id() & 0x7) << 5

		if (can_mask.get_id_extension()):
			data_byte |= ((can_mask.get_extended_id() & (0x3 << 16)) >> 16)
			data_bytes_to_send.append(data_byte)

			data_byte = (can_mask.get_extended_id() & (MCP2515.BYTE_MASK  << 8)) >> 8
			data_bytes_to_send.append(data_byte)

			data_byte = (can_mask.get_extended_id() & MCP2515.BYTE_MASK)
			data_bytes_to_send.append(data_byte)
		else:
			data_bytes_to_send.append(data_byte)

			data_byte = (can_mask.get_data_byte0() & MCP2515.BYTE_MASK)
			data_bytes_to_send.append(data_byte)

			data_byte = (can_mask.get_data_byte1() & MCP2515.BYTE_MASK)
			data_bytes_to_send.append(data_byte)

		self.write_bytes(base_mask_address, data_bytes_to_send)

	def read_rx_control_register(self, buffer_number):
		rx_control_register_address = 0x60 if (buffer_number == 0) else 0x70
		return self.read_bytes(rx_control_register_address, num_bytes=1)

	def read_rx_buffer(self, buffer_number, expected_num_data_bytes=8):
		# RX Buffer Number = [0, 1]
		bytes_to_write = []
		num_bytes_to_receive = 5 + expected_num_data_bytes

		# RXnIF Flag automatically cleared when using READ RX BUFFER Command
		read_rx_command = MCP2515.READ_RX_BUFFER_INSTRUCTION_BASE_BYTE | (buffer_number << 2)
		bytes_to_write.append(read_rx_command)
		bytes_to_write.extend([0] * num_bytes_to_receive)

		bytes_read = self.spi_instance.xfer2(bytes_to_write)
		return bytes_read[1:]

	def interpret_rx_buffer(self, received_buffer_bytes):
		can_rx_message = CANMessageBuffer()

		standard_id = (received_buffer_bytes[0] << 3) | ((received_buffer_bytes[1] & (0x07 << 5)) >> 5)
		can_rx_message.set_standard_id(standard_id)

		ide = (received_buffer_bytes[1] & (0x01 << 3)) >> 3
		can_rx_message.set_id_extension(ide)

		if ide:
			extended_id = (received_buffer_bytes[1] & 0x03) << 16
			extended_id |= (received_buffer_bytes[2] & MCP2515.BYTE_MASK) << 8
			extended_id |= (received_buffer_bytes[3] & MCP2515.BYTE_MASK)
			can_rx_message.set_extended_id(extended_id)

			rtr = (received_buffer_bytes[4] & (0x01 << 6)) >> 6
			can_rx_message.set_remote_transmission(rtr)
		else:
			can_rx_message.set_extended_id(0)
			rtr = (received_buffer_bytes[1] & (0x01 << 4)) >> 4
			can_rx_message.set_remote_transmission(rtr)

		num_data_bytes = received_buffer_bytes[4] & 0x0F
		expected_num_data_bytes = len(received_buffer_bytes) - 5
		num_data_bytes_to_read = min(num_data_bytes, expected_num_data_bytes)
		starting_data_index = 5
		ending_data_index = starting_data_index + num_data_bytes_to_read
		can_rx_message.set_data_bytes(received_buffer_bytes[starting_data_index:ending_data_index])

		return can_rx_message

	def wait_until_message_received(self, rx_buffer_number):
		rx_message_received = False
		while (not rx_message_received):
			byte_read = self.get_status()[0]
			bit_mask = (0x01 << rx_buffer_number)
			rx_message_received = True if (byte_read & bit_mask) else False
		return rx_message_received

	def configure_rx_buffer(self, rx_buffer_number, is_filters_enabled=True, buffer_rollover=False):
		# Only RX Buffer 0 has the Buffer Overflow Option
		# Add additional bit to bit mask to allow buffer rollover control
		if rx_buffer_number == 0:
			mask_byte = 0x64
		else:
			mask_byte = 0x60
		
		data_byte = 0x00 if is_filters_enabled else (0x03 << 5)
		data_byte |= (0x01 << 2) if buffer_rollover else 0x00 

		# Modify Individual Bits of Control Register (CR)
		bytes_to_write = [
			MCP2515.BIT_MODIFY_INSTRUCTION_BYTE,
			MCP2515.CAN_BUFFER_NUMBER_TO_CR_ADDRESS[rx_buffer_number],
			mask_byte,
			data_byte
		]
		self.spi_instance.xfer2(bytes_to_write)
コード例 #28
0
class LocalPiHardwareSPI(SPI, Device):
    def __init__(self, factory, port, device):
        self._port = port
        self._device = device
        self._interface = None
        if SpiDev is None:
            raise ImportError('failed to import spidev')
        super(LocalPiHardwareSPI, self).__init__()
        pins = SPI_HARDWARE_PINS[port]
        self.pin_factory.reserve_pins(self, pins['clock'], pins['mosi'],
                                      pins['miso'], pins['select'][device])
        self._interface = SpiDev()
        self._interface.open(port, device)
        self._interface.max_speed_hz = 500000

    def close(self):
        if self._interface is not None:
            self._interface.close()
        self._interface = None
        self.pin_factory.release_all(self)
        super(LocalPiHardwareSPI, self).close()

    @property
    def closed(self):
        return self._interface is None

    def __repr__(self):
        try:
            self._check_open()
            return 'SPI(port=%d, device=%d)' % (self._port, self._device)
        except DeviceClosed:
            return 'SPI(closed)'

    def transfer(self, data):
        """
        Writes data (a list of integer words where each word is assumed to have
        :attr:`bits_per_word` bits or less) to the SPI interface, and reads an
        equivalent number of words, returning them as a list of integers.
        """
        return self._interface.xfer2(data)

    def _get_clock_mode(self):
        return self._interface.mode

    def _set_clock_mode(self, value):
        self._interface.mode = value

    def _get_lsb_first(self):
        return self._interface.lsbfirst

    def _set_lsb_first(self, value):
        self._interface.lsbfirst = bool(value)

    def _get_select_high(self):
        return self._interface.cshigh

    def _set_select_high(self, value):
        self._interface.cshigh = bool(value)

    def _get_bits_per_word(self):
        return self._interface.bits_per_word

    def _set_bits_per_word(self, value):
        self._interface.bits_per_word = value
コード例 #29
0
class SPIimplementation(SPI):
    """SPI imlementation wrapping spidev library. Extends :class:`SPI`.
    
    Args:
        port (int): SPI port on raspberry pi.
        devive (int): SPI device of raspberry.

    Raises:
        ImportError: If spidev is not installed.
    """
    def __init__(self, port, device):
        self._port = port
        self._device = device
        self._interface = None
        if SpiDev is None:
            raise ImportError('failed to import spidev')
        self._interface = SpiDev()
        self._interface.open(port, device)
        self._interface.max_speed_hz = 1000000

    def read(self, n):
        """Read n words from spi
        
        Args:
            n (int): The number of bytes to read from spi.
        """
        return self._interface.readbytes(n)

    # TODO: Check writebytes2 for large lists
    def write(self, data):
        """Write data to spi
        
        Args:
            data (list): A list with integers to be writter to the device.
        """

        self._interface.writebytes2(data)

    def read_write(self, data):
        """
        Writes data (a list of integer words where each word is assumed to have
        :attr:`bits_per_word` bits or less) to the SPI interface, and reads an
        equivalent number of words, returning them as a list of integers.
        """
        return self._interface.xfer2(data)

    def close(self):
        if self._interface is not None:
            self._interface.close()
        self._interface = None

    def _get_clock_mode(self):
        return self._interface.mode

    def _set_clock_mode(self, value):
        self._interface.mode = value

    def _get_lsb_first(self):
        return self._interface.lsbfirst

    def _set_lsb_first(self, value):
        self._interface.lsbfirst = bool(value)

    def _get_select_high(self):
        return self._interface.cshigh

    def _set_select_high(self, value):
        self._interface.cshigh = bool(value)

    def _get_bits_per_word(self):
        return self._interface.bits_per_word

    def _set_bits_per_word(self, value):
        self._interface.bits_per_word = value