예제 #1
0
class Newport:
    direction = 0xff  # gpio direction byte

    def __init__(self, address='ftdi://ftdi:232/1'):
        self.gpio = GpioController()
        self.state = None
        self.address = address

    def __del__(self):
        self.disconnect()

    def connect(self):
        self.gpio.open_from_url(self.address, direction=self.direction)
        self.state = self.gpio.read()

    def disconnect(self):
        self.gpio.close()

    def on(self):
        self.gpio.write(0x00)
        self.state = self.gpio.read()

    def off(self):
        self.gpio.write(0xff)
        self.state = self.gpio.read()
예제 #2
0
class LEDTest():
    """Test for LED on FT232H board"""
    def __init__(self):
        self._gpio = GpioController()
        self._state = 0  # SW cache of the GPIO output lines
        
    def pins(self):
        print(self._gpio.direction)
    
    def open(self, out_pins):
        """Open a GPIO connection, defining which pins are configured as
           output and input"""
        out_pins &= 0xFF
        url = environ.get('FTDI_DEVICE', 'ftdi://ftdi:232h/1')
        self._gpio.open_from_url(url, direction=out_pins)
        
    def close(self):
        """Close the GPIO connection"""
        self._gpio.close()
        
    def get_gpio(self, line):
        """Retrieve the level of a GPIO input pin

           :param line: specify which GPIO to read out.
           :return: True for high-level, False for low-level
        """
        value = self._gpio.read_port()
        print(value)
        return bool(value & (1 << line))
        
    def set_gpio(self, line, on):
        """Set the level of a GPIO ouput pin.

           :param line: specify which GPIO to madify.
           :param on: a boolean value, True for high-level, False for low-level
        """
        if on:
            state = self._state | (1 << line)
        else:
            state = self._state & ~(1 << line)
        self._commit_state(state)

        
    def _commit_state(self, state):
        """Update GPIO outputs
        """
        self._gpio.write_port(state)
        # do not update cache on error
        self._state = state
예제 #3
0
파일: gpio.py 프로젝트: eblot/pyftdi
class GpioTest(object):
    """
    """

    def __init__(self):
        self._gpio = GpioController()
        self._state = 0  # SW cache of the GPIO output lines

    def open(self, out_pins):
        """Open a GPIO connection, defining which pins are configured as
           output and input"""
        out_pins &= 0xFF
        url = environ.get('FTDI_DEVICE', 'ftdi://ftdi:2232h/1')
        self._gpio.open_from_url(url, direction=out_pins)

    def close(self):
        """Close the GPIO connection"""
        self._gpio.close()

    def set_gpio(self, line, on):
        """Set the level of a GPIO ouput pin.

           :param line: specify which GPIO to madify.
           :param on: a boolean value, True for high-level, False for low-level
        """
        if on:
            state = self._state | (1 << line)
        else:
            state = self._state & ~(1 << line)
        self._commit_state(state)

    def get_gpio(self, line):
        """Retrieve the level of a GPIO input pin

           :param line: specify which GPIO to read out.
           :return: True for high-level, False for low-level
        """
        value = self._gpio.read_port()
        return bool(value & (1 << line))

    def _commit_state(self, state):
        """Update GPIO outputs
        """
        self._gpio.write_port(state)
        # do not update cache on error
        self._state = state
예제 #4
0
#!/usr/bin/env python3

# deps can be satisfied on Linux with `sudo pip3 install pyftdi`

from pyftdi.gpio import GpioController, GpioException
from time import sleep
import sys
import serial
import bitstring

bitstring.bytealigned = True  # change the default behaviour

bitbang = GpioController()
bitbang.open_from_url('ftdi:///1')

ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=None)

DELAY = 0.0000005  #strict worst-case delay is 0.54ms -- we can relax that due to lots of delays in the many layers of software between us.
#on my machine this results in a minimum CLK pulse width of 0.58 ms on my machine
HARD_DELAY = 0.00054  # for cases where strict delay adherence is necessary (e.g. when begining shift-out)

state = 0


def pin_output(line):
    bitbang.set_direction(1 << line, 1 << line)
    return


def pin_input(line):
    bitbang.set_direction(1 << line, 0)
예제 #5
0
class Executor(multiprocessing.Process):
    '''
    Provides an executor - responsible for banging data onto and off of the
    wire - which is intended to be run in a separate process. This also
    handles timing and has been built to use queues to try and reduce clock
    jitter.

    This was lifted from whatabanger with slight modifications.
    '''
    def __init__(self, req, res, clk=0x01, mosi=0x02, miso=0x04, cs=0x08):
        ''' Ensure a logger is setup, and access to the GPIO is possible. '''
        super(Executor, self).__init__()
        self.log = logging.getLogger(__name__)

        # The initial state is everything pulled HIGH.
        self.state = 0xFF

        # Ensure the work queue is accessible - this is used for the parent
        # to push request to bang onto the wire.
        self._in = req
        self._out = res

        # Defaults are:
        #     Pin D0 - 0x01 - OUT (CLOCK)
        #     Pin D1 - 0x02 - OUT (MOSI)
        #     Pin D2 - 0x04 - IN  (MISO)
        #     Pin D3 - 0x08 - OUT (CHIP SELECT)
        self.clk = clk
        self.miso = miso
        self.mosi = mosi
        self.cs = cs

        # Setup the clock interval. This isn't the cycle time, but half the
        # target cycle time.
        self.clock_interval = 0.0

        # Setup the interface, ensuring that MISO is set to GPIO IN.
        self.gpio = GpioController()
        direction = xor(0xFF, self.miso)
        self.log.debug("Setting up FT2232 for GPIO (%s)",
                       "{0:08b}".format(direction))
        self.gpio.open_from_url(
            url='ftdi://0x0403:0x6010/1',
            direction=direction,
        )

        # Set the initial GPIO state.
        self.gpio.write_port(self.state)
        self.log.debug("Set the initial GPIO state to %s", self.state)

    def _write_bits(self, bits):
        ''' Write bits onto the wire (Master to Target) communication. '''
        self.log.debug("Starting banging bits (%s)", bits)

        for bit in bits:
            # Pull the clock HIGH, and drive CS low.
            self.state |= self.clk
            self.state &= ~self.cs
            self.gpio.write_port(self.state)
            time.sleep(self.clock_interval)

            # Check whether we need to write a HIGH or LOW for the bit to be
            # transmitted (where HIGH is 1).
            if bit == 1:
                self.state |= self.mosi
            else:
                self.state &= ~self.mosi

            # Send data via MOSI on the FALLING-edge of the clock.
            self.state &= ~self.clk
            self.gpio.write_port(self.state)
            time.sleep(self.clock_interval)

        # If there's not a Logic Analyser connected, determining when all
        # data has been sent is a pain. Thus, this.
        self.log.debug("Finished banging bits")

    def _read_bits(self, count):
        ''' Reads N bits from the wire. '''
        self.log.debug("Reading %s bits", count)

        # This should already be the case, but ensure MISO isn't drive by
        # the master (us).
        self.gpio.set_direction(self.miso, 0x0)

        result = []
        for _ in range(count):
            # Data will be banged onto the wire by the target device on the
            # RISING edge.
            self.state |= self.clk
            self.gpio.write_port(self.state)

            # Finally, read the state of MISO to determine the value sent by
            # the target.
            if (self.gpio.read() & self.miso) == self.miso:
                result.append(1)
            else:
                result.append(0)

            # Sleep and then drive the clock LOW to complete the cycle.
            time.sleep(self.clock_interval)
            self.state &= ~self.clk
            self.gpio.write_port(self.state)
            time.sleep(self.clock_interval)

        self.log.debug("Read %s", result)
        return result

    def _write_clock(self):
        ''' 'Write' a clock cycle without sending any data. '''
        # Pull the clock HIGH.
        self.state |= self.clk
        self.gpio.write_port(self.state)
        time.sleep(self.clock_interval)

        # Pull the clock LOW.
        self.state &= ~self.clk
        self.gpio.write_port(self.state)
        time.sleep(self.clock_interval)

    def run(self):
        ''' Run the clock, and bang bits as required. '''
        self.log.info("Bit banger clock and monitor started")
        while True:
            # If there's anything in the queue, bang away.
            if self._in.qsize() > 0:
                request = self._in.get()
                self._write_bits(request['bits'])
                r = 0
                while r <= request['size']:
                    result = self._read_bits(8)
                    r += 8
                    self._out.put(result)
            else:
                # If no data is pending send, make sure we still drive the
                # clock.
                self._write_clock()
예제 #6
0
        self.i2c_end()
        return v

    def i2c_read_from_reg(self, reg):
        """Reads a single byte from specified register.

		:param reg: Register to be read.
		:return: Byte that was read.
		"""
        v = self.i2c_write_address(0, self.address)
        v &= self.i2c_write_byte(reg)
        self.i2c_end()
        v &= self.i2c_write_address(1, self.address)
        byte = self.i2c_read_byte()
        if not v:
            print("Error")
        self.i2c_end()
        return byte


if __name__ == '__main__':
    mask = 0x13  # in, in,in  Out, In, In, out, out
    gpio = GpioController()
    gpio.open_from_url('ftdi://ftdi:4232h/1', mask)
    port = I2CPort(gpio)
    switch2 = I2CDevice(port, 0x71)
    switch2.i2c_write_byte_to(0x04)
    i = switch2.i2c_read_byte_from()
    print("%x" % i)
    gpio.close()
예제 #7
0
class PapilioOne(PyFTDIGPIOAdapter):
    """ 
        A JTAG adapter for Papilio One devices ported to use PyFTDI python library instead of libftdi.
    """

    #VID/PID constants.
    VENDOR_ID = 0x0403
    PRODUCT_ID = 0x6010

    #Port-number constants.
    TCK_PORT = 0
    TDI_PORT = 1
    TDO_PORT = 2
    TMS_PORT = 3

    DEFAULT_FREQ = int(1e6)
    FTDI_URL = 'ftdi://0x{:04x}:0x{:04x}/1'.format(VENDOR_ID, PRODUCT_ID)

    def __init__(self, serial_number=None, debug=False):
        """
            Create a new instance of the Papilio One.

            serial_number -- The serial number of the board to connect to, or None to use
                             the first available bitbangable FTDI. Use caution with this one!
                             NOTE: This is IGNORED.
        """

        # Instead of using BitBangDevice(), use GpioController() from PyFTDI
        self._gpio = GpioController()

        # If FTDI_DEVICE environment variable, use it instead of self.FTDI_URL
        url = environ.get('FTDI_DEVICE', self.FTDI_URL)

        # Open the PyFTDI URL with outputs set as per set_up_jtag_port()
        self._gpio.open_from_url(url, direction=self.set_up_jtag_port())

        atexit.register(self.cleanup)

        #Initiatialize the core JTAG subsystem.
        super().__init__(self._gpio)

    def cleanup(self):
        print("Running PyFTDI GPIO cleanup...")
        self._gpio.close()

    def set_tck_period(self, period):
        """
            Handle the settck virtual cable command which requests a certain TCK period. Return the actual period.
        """

        #@@@# Modify to actually change frequency using PyFTDI functions.

        ## Actual Period depends on many factors since this tries to simply go as fast as it can. So nothing to set. Respond that it goes at 100 Hz or 10e6 ns
        return int(1e9 // self.DEFAULT_FREQ)

    def set_up_jtag_port(self):
        direction = 0
        direction |= (1 << self.TCK_PORT)
        direction |= (1 << self.TDI_PORT)
        direction |= (1 << self.TMS_PORT)
        direction &= ~(1 << self.TDO_PORT)
        return direction

    def set_tms(self, value, commit=True):
        """
            Specifies the value of the TMS port. Used by the parent class.
        """
        self._set_bit(self.TMS_PORT, value, commit)

    def set_tdi(self, value, commit=True):
        """
            Specifies the value of the TDI port. Used by the parent class.
        """
        self._set_bit(self.TDI_PORT, value, commit)

    def set_tck(self, value, commit=True):
        """
            Specifies the value of the TCK port. Used by the parent class.
        """
        self._set_bit(self.TCK_PORT, value, commit)

    def get_tdo(self):
        """
            Reads the current value of the TDO port. Used by the parent class.
        """
        return self._get_bit(self.TDO_PORT)