def begin(self): try: self.ctrl = SpiController(cs_count=1) s = 'ftdi://0x0403:0x6011/1' self.ctrl.configure(s) self.slave = self.ctrl.get_port(cs=0, freq=6E6, mode=3) self.slave.set_frequency(8000000) self.gpio = self.ctrl.get_gpio() self.gpio.set_direction( 0x10, 0x10) # direction for the fet controller is OUTPUT (1) self.gpio.write(0x10) time.sleep(0.1) # to account for using separate ports for power and comms: self.backup_ctrl = SpiController(cs_count=1) self.backup_gpio = None if not s == 'ftdi://0x0403:0x6011/1': backup_s = 'ftdi://0x0403:0x6011/1' self.backup_ctrl.configure(backup_s) self.backup_gpio = self.backup_ctrl.get_gpio() self.backup_gpio.set_direction(0x10, 0x10) self.backup_gpio.write(0x10) time.sleep(1) except Exception as err: print('Error in initialising the FTDI driver ...:', err)
def __init__(self, spi_frequency=5e6): # Params self.spi_frequency = spi_frequency # SPI link self.spi = SpiController(cs_count=3) self.spi.configure('ftdi://ftdi:2232h/1') self.slave = self.spi.get_port(cs=2, freq=self.spi_frequency, mode=0)
def __init__(self): # Instanciate a SPI controller self._spi = SpiController() # Configure the first interface (IF/1) of the FTDI device as a SPI master self._spi.configure('ftdi://ftdi:2232h/2') # Get a SPI port to a SPI slave w/ /CS on A*BUS3 and SPI mode 0 @ 12MHz self._slave = self._spi.get_port(cs=1, freq=500e3, mode=0)
def test_usb_device(self): """Demo instanciation from an existing UsbDevice. """ candidate = Ftdi.get_identifiers(self.ftdi_url) usbdev = UsbTools.get_device(candidate[0]) spi = SpiController(cs_count=1) spi.configure(usbdev, interface=candidate[1]) flash = SerialFlashManager.get_from_controller(spi, cs=0, freq=self.frequency)
def __init__(self, device='ftdi://ftdi:232h/1', debug=False): self.device_str = device self.debug = debug self.ctrl = SpiController(silent_clock=False) self.ctrl.configure(device, cs_count=1) self.spi = self.ctrl.get_port(cs=0, freq=100000) self.gpio = self.ctrl.get_gpio() direction = self.gpio.direction self.gpio.set_direction(0x30, 0x10) # Add reset as output self.gpio.write(0x10)
class SPI: MSB = 0 def __init__(self): from pyftdi.spi import SpiController self._spi = SpiController(cs_count=1) self._spi.configure('ftdi://ftdi:ft232h/1') self._port = self._spi.get_port(0) print(self._port) dir(self._port) self._port.set_frequency(100000) self._port._cpol = 0 self._port._cpha = 0 # Change GPIO controller to SPI Pin.ft232h_gpio = self._spi.get_gpio() def init(self, baudrate=100000, polarity=0, phase=0, bits=8, firstbit=MSB, sck=None, mosi=None, miso=None): self._port.set_frequency(baudrate) # FTDI device can only support mode 0 and mode 2 # due to the limitation of MPSSE engine. # This means CPHA must = 0 self._port._cpol = polarity if phase != 0: raise ValueError("Only SPI phase 0 is supported by FT232H.") self._port._cpha = phase @property def frequency(self): return self._port.frequency def write(self, buf, start=0, end=None): end = end if end else len(buf) chunks, rest = divmod(end - start, self._spi.PAYLOAD_MAX_LENGTH) for i in range(chunks): chunk_start = start + i * self._spi.PAYLOAD_MAX_LENGTH chunk_end = chunk_start + self._spi.PAYLOAD_MAX_LENGTH self._port.write(buf[chunk_start:chunk_end]) if rest: self._port.write(buf[-1*rest:]) def readinto(self, buf, start=0, end=None, write_value=0): end = end if end else len(buf) result = self._port.read(end-start) for i, b in enumerate(result): buf[start+i] = b def write_readinto(self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None): out_end = out_end if out_end else len(buffer_out) in_end = in_end if in_end else len(buffer_in) result = self._port.exchange(buffer_out[out_start:out_end], in_end-in_start, duplex=True) for i, b in enumerate(result): buffer_in[in_start+i] = b
def get_flash_device(url, cs=0, freq=None): """Obtain an instance of the detected flash device""" ctrl = SpiController(silent_clock=False) ctrl.configure(url) spi = ctrl.get_port(cs, freq) jedec = SerialFlashManager.read_jedec_id(spi) if not jedec: # it is likely that the latency setting is too low if this # condition is encountered raise SerialFlashUnknownJedec("Unable to read JEDEC Id") flash = SerialFlashManager._get_flash(spi, jedec) flash.set_spi_frequency(freq) return flash
def initialize(): global spi global gpio # Configure controller with one CS ctrl = SpiController(cs_count=1, turbo=True) # ctrl.configure('ftdi:///?') # Use this if you're not sure which device to use # Windows users: make sure you've loaded libusb-win32 using Zadig try: ctrl.configure(config.FTDI_URL) except: print("Can't configure FTDI. Possible reasons:") print( " 1. As a current Linux user you don't have an access to the device.\n" " Solution: https://eblot.github.io/pyftdi/installation.html\n" " 2. You use the wrong FTDI URL. Replace FTDI_URL in config.py with one of the following:\n" ) ctrl.configure('ftdi:///?') sys.exit(1) # Get SPI slave # CS0, 10MHz, Mode 0 (CLK is low by default, latch on the rising edge) spi = ctrl.get_port(cs=0, freq=10E6, mode=0) # Get GPIO gpio = ctrl.get_gpio() gpio.set_direction(0x10, 0x10)
def setConfigure(ftdi_interface, ccp_header_file): spi = SpiController() spi.configure(ftdi_interface) global slave slave = spi.get_port(cs=0, freq=12E6, mode=0) global ccp_header ccp_header = cpp_header_parser.read_header(ccp_header_file) def makeup_data(keylist): return [ReadFromCppHeader(key) for key in keylist] blockWrite(ccp_header["gpo_data_15_to_0"], makeup_data(configDesignVals)) blockWrite(ccp_header["port_cfg_00"], makeup_data(portConfigDesignVals)) blockWrite(ccp_header["dac_data_port_00"], makeup_data(dacDesignVals))
class SPI: MSB = 0 def __init__(self): from pyftdi.spi import SpiController self._spi = SpiController(cs_count=1) self._spi.configure('ftdi:///1') self._port = self._spi.get_port(0) self._port.set_frequency(100000) self._port._cpol = 0 self._port._cpha = 0 # Change GPIO controller to SPI Pin.ft232h_gpio = self._spi.get_gpio() def init(self, baudrate=100000, polarity=0, phase=0, bits=8, firstbit=MSB, sck=None, mosi=None, miso=None): self._port.set_frequency(baudrate) self._port._cpol = polarity self._port._cpha = phase @property def frequency(self): return self._port.frequency def write(self, buf, start=0, end=None): end = end if end else len(buf) chunks, rest = divmod(end - start, self._spi.PAYLOAD_MAX_LENGTH) for i in range(chunks): chunk_start = start + i * self._spi.PAYLOAD_MAX_LENGTH chunk_end = chunk_start + self._spi.PAYLOAD_MAX_LENGTH self._port.write(buf[chunk_start:chunk_end]) if rest: self._port.write(buf[-1*rest:]) def readinto(self, buf, start=0, end=None, write_value=0): end = end if end else len(buf) result = self._port.read(end-start) for i, b in enumerate(result): buf[start+i] = b def write_readinto(self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None): out_end = out_end if out_end else len(buffer_out) in_end = in_end if in_end else len(buffer_in) result = self._port.exchange(buffer_out[out_start:out_end], in_end-in_start, duplex=True) for i, b in enumerate(result): buffer_in[in_start+i] = b
class PanelControl(object): def __init__(self, spi_frequency=5e6): # Params self.spi_frequency = spi_frequency # SPI link self.spi = SpiController(cs_count=3) self.spi.configure('ftdi://ftdi:2232h/1') self.slave = self.spi.get_port(cs=2, freq=self.spi_frequency, mode=0) def reg_w16(self, reg, v): self.slave.exchange([reg, v >> 8, v & 0xff]) def reg_w8(self, reg, v): self.slave.exchange([reg, v]) def read_status(self): rv = self.slave.exchange([0x00, 0x00], duplex=True) return rv[0] | rv[1] def send_data(self, data): self.slave.exchange([0x80] + data) def send_frame(self, frame, width=64, height=64, bits=16): # Size of a line ll = width * bits // 8 # Scan all line for y in range(height): # Send write command to line buffer self.send_data(list(frame[y*ll:(y+1)*ll])) # Swap line buffer & Write it to line y of back frame buffer self.reg_w8(0x03, y) # Send frame swap command panel.reg_w8(0x04, 0x00) # Wait for the frame swap to occur while (panel.read_status() & 0x02 == 0): pass
class SpiAccelTest(object): """Basic test for an ADXL345 device selected as CS1, SPI mode 3 """ def __init__(self): self._spi = SpiController() def open(self): """Open an I2c connection to a slave""" self._spi.configure('ftdi://ftdi:2232h/1') def read_device_id(self): port = self._spi.get_port(1, freq=6E6, mode=3) device_id = port.exchange([0x00], 1).tobytes() hex_device_id = hexlify(device_id).decode() print('DEVICE ID:', hex_device_id) return hex_device_id def close(self): """Close the I2C connection""" self._spi.terminate()
class SpiDataFlashTest(object): """Basic test for a MX25L1606E data flash device selected as CS0, SPI mode 0 """ def __init__(self): self._spi = SpiController() def open(self): """Open an I2c connection to a slave""" self._spi.configure('ftdi://ftdi:2232h/1') def read_jedec_id(self): port = self._spi.get_port(0, freq=3E6, mode=0) jedec_id = port.exchange([0x9f], 3).tobytes() hex_jedec_id = hexlify(jedec_id).decode() print('JEDEC ID:', hex_jedec_id) return hex_jedec_id def close(self): """Close the I2C connection""" self._spi.terminate()
class EpdFtdiPort: """ """ DC_PIN = 1 << 5 RESET_PIN = 1 << 6 BUSY_PIN = 1 << 7 I_PINS = BUSY_PIN O_PINS = DC_PIN | RESET_PIN IO_PINS = I_PINS | O_PINS def __init__(self, debug=False): self._debug = debug self._spi = SpiController(cs_count=2) self._spi_port = None self._io_port = None self._io = 0 def open(self, url=None): """Open an SPI connection to a slave""" url = environ.get('FTDI_DEVICE', url or 'ftdi:///1') self._spi.configure(url, debug=self._debug) self._spi_port = self._spi.get_port(0, freq=10E6, mode=0) self._io_port = self._spi.get_gpio() self._io_port.set_direction(self.IO_PINS, self.O_PINS) def close(self): """Close the SPI connection""" self._spi.terminate() def reset(self): self._io = self.RESET_PIN self._io_port.write(self._io) sleep(0.2) self._io = 0 self._io_port.write(self._io) sleep(0.2) self._io = self.RESET_PIN self._io_port.write(self._io) sleep(0.2) def write_command(self, cmd): if isinstance(cmd, int): data = bytes([cmd]) self._io &= ~self.DC_PIN self._io_port.write(self._io) self._spi_port.write(data) def write_data(self, data): if isinstance(data, int): data = bytes([data]) self._io |= self.DC_PIN self._io_port.write(self._io) self._spi_port.write(data) def wait_ready(self): start = now() while self._io_port.read() & self.BUSY_PIN: sleep(0.05) return now() - start
def __init__(self, ftdi_url, spi_freq=1E6): """Configure the FTDI interface. Keyword arguments: ftdi_url -- device url, which can be obtained by Ftdi.show_devices() freq -- SPI frequency up to 8E6 (for FPGA running on 64 MHz) """ # Configure SPI master self._spi_ctrl = SpiController() self._spi_ctrl.configure(ftdi_url + '2') # second port - channel B self._spi_port = self._spi_ctrl.get_port(cs=0, freq=spi_freq, mode=0) # Configure FPGA logic reset (ICE_RESET_FT) self._spi_gpio = self._spi_ctrl.get_gpio() self._spi_gpio.set_direction(1 << self.GPIO_RESET_LOGIC_POS, 1 << self.GPIO_RESET_LOGIC_POS) self._spi_gpio.write(0) # Configure FPGA configuration reset (ICE_RESET) self._gpio_ctrl = GpioAsyncController() self._gpio_ctrl.configure(ftdi_url + '1', # first port - channel A direction=(1 << self.GPIO_RESET_CONFIG_POS), frequency=1e6, initial=(1 << self.GPIO_RESET_CONFIG_POS)) self._gpio_ctrl.write(1 << self.GPIO_RESET_CONFIG_POS)
class SpiRfda2125Test(object): """Basic test for a RFDA2125 Digital Controlled Variable Gain Amplifier selected as CS2, SPI mode 0 """ def __init__(self): self._spi = SpiController() def open(self): """Open an I2c connection to a slave""" self._spi.configure('ftdi://ftdi:2232h/1') self._port = self._spi.get_port(2, freq=1E6, mode=0) def change_attenuation(self, value): if not (0.0 <= value <= 31.5): print('Out-of-bound attenuation', file=stderr) intval = 63 - int(value * 2) self._port.write(bytes([intval]), 1) def close(self): """Close the I2C connection""" self._spi.terminate()
class SpiAccelTest(object): """Basic test for an ADXL345 device selected as CS1, SPI mode 3 """ def __init__(self): self._spi = SpiController(cs_count=3) def open(self): """Open an SPI connection to a slave""" url = environ.get('FTDI_DEVICE', 'ftdi://ftdi:2232h/1') self._spi.configure(url) def read_device_id(self): port = self._spi.get_port(1, freq=6E6, mode=3) device_id = port.exchange([0x00], 1).tobytes() hex_device_id = hexlify(device_id).decode() print('DEVICE ID:', hex_device_id) return hex_device_id def close(self): """Close the SPI connection""" self._spi.terminate()
class SpiDataFlashTest(object): """Basic test for a MX25L1606E data flash device selected as CS0, SPI mode 0 """ def __init__(self): self._spi = SpiController(cs_count=3) def open(self): """Open an SPI connection to a slave""" url = environ.get('FTDI_DEVICE', 'ftdi://ftdi:2232h/1') self._spi.configure(url) def read_jedec_id(self): port = self._spi.get_port(0, freq=3E6, mode=0) jedec_id = port.exchange([0x9f], 3).tobytes() hex_jedec_id = hexlify(jedec_id).decode() print('JEDEC ID:', hex_jedec_id) return hex_jedec_id def close(self): """Close the SPI connection""" self._spi.terminate()
class SpiRfda2125Test(object): """Basic test for a RFDA2125 Digital Controlled Variable Gain Amplifier selected as CS2, SPI mode 0 """ def __init__(self): self._spi = SpiController(cs_count=3) def open(self): """Open an SPI connection to a slave""" url = environ.get('FTDI_DEVICE', 'ftdi://ftdi:2232h/1') self._spi.configure(url) self._port = self._spi.get_port(2, freq=1E6, mode=0) def change_attenuation(self, value): if not (0.0 <= value <= 31.5): print('Out-of-bound attenuation', file=stderr) intval = 63-int(value*2) self._port.write(bytes([intval]), 1) def close(self): """Close the SPI connection""" self._spi.terminate()
class SpiGpioTestCase(unittest.TestCase): """Basic test for GPIO access w/ SPI mode It expects the following I/O setup: AD4 connected t0 AC0 AD5 connected t0 AC1 AD6 connected t0 AC2 AD7 connected t0 AC3 """ # AD0: SCLK, AD1: MOSI, AD2: MISO, AD3: /CS AD_OFFSET = 4 AC_OFFSET = 8 PIN_COUNT = 4 def setUp(self): self._spi = SpiController(cs_count=1) url = environ.get('FTDI_DEVICE', 'ftdi://ftdi:2232h/1') self._spi.configure(url) self._port = self._spi.get_port(0, freq=1E6, mode=0) self._io = self._spi.get_gpio() def tearDown(self): """Close the SPI connection""" self._spi.terminate() def test_ac_to_ad(self): ad_pins = ((1 << self.PIN_COUNT) - 1) << self.AD_OFFSET # input ac_pins = ((1 << self.PIN_COUNT) - 1) << self.AC_OFFSET # output io_pins = ad_pins | ac_pins def ac_to_ad(ac_output): ac_output &= ac_pins ac_output >>= self.AC_OFFSET - self.AD_OFFSET return ac_output & ad_pins self._io.set_direction(io_pins, ac_pins) for ac in range(1 << self.PIN_COUNT): ac_out = ac << self.AC_OFFSET ad_in = ac_to_ad(ac_out) self._io.write(ac_out) # random SPI exchange to ensure SPI does not change GPIO self._port.exchange([0x00, 0xff], 2) rd = self._io.read() self.assertEqual(rd, ad_in) self.assertRaises(SpiIOError, self._io.write, ad_pins) def test_ad_to_ac(self): ad_pins = ((1 << self.PIN_COUNT) - 1) << self.AD_OFFSET # output ac_pins = ((1 << self.PIN_COUNT) - 1) << self.AC_OFFSET # input io_pins = ad_pins | ac_pins def ad_to_ac(ad_output): ad_output &= ad_pins ad_output <<= self.AC_OFFSET - self.AD_OFFSET return ad_output & ac_pins self._io.set_direction(io_pins, ad_pins) for ad in range(1 << self.PIN_COUNT): ad_out = ad << self.AD_OFFSET ac_in = ad_to_ac(ad_out) self._io.write(ad_out) # random SPI exchange to ensure SPI does not change GPIO self._port.exchange([0x00, 0xff], 2) rd = self._io.read() self.assertEqual(rd, ac_in) self.assertRaises(SpiIOError, self._io.write, ac_pins)
def __init__(self, vendor, product, interface=1): self._ctrl = SpiController(silent_clock=False) self._ctrl.configure(vendor, product, interface)
class SerialFlashManager(object): """Serial flash manager. Automatically detects and instanciate the proper flash device class based on the JEDEC identifier which is read out from the device itself. """ CMD_JEDEC_ID = 0x9F def __init__(self, vendor, product, interface=1): self._ctrl = SpiController(silent_clock=False) self._ctrl.configure(vendor, product, interface) def get_flash_device(self, cs=0): """Obtain an instance of the detected flash device""" spi = self._ctrl.get_port(cs) jedec = SerialFlashManager.read_jedec_id(spi) if not jedec: # it is likely that the latency setting is too low if this # condition is encountered raise SerialFlashUnknownJedec("Unable to read JEDEC Id") return SerialFlashManager._get_flash(spi, jedec) @staticmethod def read_jedec_id(spi): """Read flash device JEDEC identifier (3 bytes)""" jedec_cmd = Array('B', [SerialFlashManager.CMD_JEDEC_ID]) return spi.exchange(jedec_cmd, 3).tostring() @staticmethod def _get_flash(spi, jedec): contents = sys.modules[__name__].__dict__ devices = [] plugin_dir = os.path.dirname(os.path.realpath(__file__)) plugin_files = [x[:-3] for x in os.listdir(plugin_dir) if (x.endswith(".py") and not x.startswith("__init__"))] sys.path.insert(0, plugin_dir) for p in plugin_files: mod = __import__(p) # print "mod: " + str(mod) sf = getattr(mod, "SerialFlash") # for sp in sf.__subclasses__(): # print "subclass: " + str(sp) # print "plugin file: " + str(p) # print "sf: " + str(sf) for name in dir (mod): if name.startswith('_'): continue obj = getattr(mod, name) if obj not in sf.__subclasses__(): continue # for p in SerialFlash.__subclasses__(): # print "subclass: " + p # print "name: " + name # print "base classes: " + str(inspect.getmro(obj)) # print "\tclass: %s is class %s" % (str(obj), str(SerialFlash)) # if not isinstance (obj, SerialFlash): # continue # if ("SerialFlash" in str(inspect.getmro(obj))): # print "found subclass" # # for bn in inspect.getmro(obj): # print "base name: " + str(bn) # # print "type: " + str(type(obj)) # print "sf type: " + str(type(SerialFlash)) # # if isclass(obj) and issubclass(obj, SerialFlash) and obj is not SerialFLash : # if isclass(obj) and "SerialFLash" not in str(obj) : # print "\t\tappend name: " + name devices.append(obj) for device in devices: if device.match(jedec): return device(spi, jedec) raise SerialFlashUnknownJedec(jedec)
def __init__(self): self._spi = SpiController(cs_count=3)
def setUp(self): self._spi = SpiController(cs_count=1) url = environ.get('FTDI_DEVICE', 'ftdi://ftdi:2232h/1') self._spi.configure(url) self._port = self._spi.get_port(0, freq=1E6, mode=0) self._io = self._spi.get_gpio()