# `i2c` - I2C API

## Quickstart

Example: communication with an I2C GPIO expander

    # Instantiate an I2C controller
    i2c = I2cController()

    # Configure the first interface (IF/1) of the FTDI device as an I2C master
    i2c.configure('ftdi://ftdi:2232h/1')

    # Get a port to an I2C slave device
    slave = i2c.get_port(0x21)

    # Send one byte, then receive one byte
    slave.exchange([0x04], 1)

    # Write a register to the I2C slave
    slave.write_to(0x06, b'\x00')

    # Read a register from the I2C slave
    slave.read_from(0x00, 1)

Example: mastering the I2C bus with a complex transaction

    from time import sleep

    port = I2cController().get_port(0x56)

    # emit a START sequence is read address, but read no data and keep the bus
    # busy
    port.read(0, relax=False)

    # wait for ~1ms
    sleep(0.001)

    # write 4 bytes, without neither emitting the start or stop sequence
    port.write(b'\x00\x01', relax=False, start=False)

    # read 4 bytes, without emitting the start sequence, and release the bus
    port.read(4, start=False)

See also pyi2cflash module and `tests/i2c.py`, which provide more detailed examples on how to use the I2C API.

## Classes

class pyftdi.i2c.I2cPort(controller, address)

  I2C port.

  An I2C port is never instanciated directly: use `I2cController.get_port()` method to obtain an I2C port.

  `relax` parameter in I2cPort methods may be used to prevent the master from releasing the I2C bus, if some further data should be exchanged with the slave device. Note that in case of any error, the I2C bus is released and the `relax` parameter is ignored in such an event.

  Example:

      >>> ctrl = I2cController()
      >>> ctrl.configure('ftdi://ftdi:232h/1')
      >>> i2c = ctrl.get_port(0x21)
      >>> # send 2 bytes
      >>> i2c.write([0x12, 0x34])
      >>> # send 2 bytes, then receive 2 bytes
      >>> out = i2c.exchange([0x12, 0x34], 2)

  property address: int

    Return the slave address.

  configure_register(bigendian=False, width=1)

    Reconfigure the format of the slave address register (if any)

    Parameters:

      - bigendian (`bool`) – True for a big endian encoding, False otherwise

      - width (`int`) – width, in bytes, of the register

    Return type:

      `None`

  exchange(out=b'', readlen=0, relax=True, start=True)

    Perform an exchange or a transaction with the I2c slave

    Parameters:

      - out (`Union`[`bytes`, `bytearray`, `Iterable`[`int`]]) – an array of bytes to send to the I2c slave, may be empty to only read out data from the slave

      - readlen (`int`) – count of bytes to read out from the slave, may be zero to only write to the slave

      - relax (`bool`) – whether to relax the bus (emit STOP) or not

      - start (`bool`) – whether to emit a start sequence (w/ address)

    Return type:

      `bytes`

    Returns:

      data read out from the slave

  flush()

    Force the flush of the HW FIFOs.

    Return type:

      `None`

  property frequency: float

    Provide the current I2c bus frequency.

  poll(write=False, relax=True, start=True)

    Poll a remote slave, expect ACK or NACK.

    Parameters:

      - write (`bool`) – poll in write mode (vs. read)

      - relax (`bool`) – whether to relax the bus (emit STOP) or not

      - start (`bool`) – whether to emit a start sequence (w/ address)

    Return type:

      `bool`

    Returns:

      True if the slave acknowledged, False otherwise

  poll_cond(width, mask, value, count, relax=True, start=True)

    Poll a remove slave, watching for condition to satisfy. On each poll cycle, a repeated start condition is emitted, without releasing the I2C bus, and an ACK is returned to the slave.

    If relax is set, this method releases the I2C bus however it leaves.

    Parameters:

      - width (`int`) – count of bytes to poll for the condition check, that is the size of the condition register

      - mask (`int`) – binary mask to apply on the condition register before testing for the value

      - value (`int`) – value to test the masked condition register against. Condition is satisfied when register & mask == value

      - count (`int`) – maximum poll count before raising a timeout

      - relax (`bool`) – whether to relax the bus (emit STOP) or not

      - start (`bool`) – whether to emit a start sequence (w/ address)

    Return type:

      `Optional`[`bytes`]

    Returns:

      the polled register value

    Raises:

      I2cTimeoutError – if poll condition is not satisified

  read(readlen=0, relax=True, start=True)

    Read one or more bytes from a remote slave

    Parameters:

      - readlen (`int`) – count of bytes to read out.

      - relax (`bool`) – whether to relax the bus (emit STOP) or not

      - start (`bool`) – whether to emit a start sequence (w/ address)

    Return type:

      `bytes`

    Returns:

      byte sequence of read out bytes

    Raises:

      I2cIOError – if device is not configured or input parameters are invalid

  read_from(regaddr, readlen=0, relax=True, start=True)

    Read one or more bytes from a given register at remote slave

    Parameters:

      - regaddr (`int`) – slave register address to read from

      - readlen (`int`) – count of bytes to read out.

      - relax (`bool`) – whether to relax the bus (emit STOP) or not

      - start (`bool`) – whether to emit a start sequence (w/ address)

    Return type:

      `bytes`

    Returns:

      data read out from the slave

    Raises:

      I2cIOError – if device is not configured or input parameters are invalid

  shift_address(offset)

    Tweak the I2C slave address, as required with some devices

  write(out, relax=True, start=True)

    Write one or more bytes to a remote slave

    Parameters:

      - out (`Union`[`bytes`, `bytearray`, `Iterable`[`int`]]) – the byte buffer to send

      - relax (`bool`) – whether to relax the bus (emit STOP) or not

      - start (`bool`) – whether to emit a start sequence (w/ address)

    Raises:

      I2cIOError – if device is not configured or input parameters are invalid

    Return type:

      `None`

  write_to(regaddr, out, relax=True, start=True)

    Write one or more bytes to a given register at a remote slave

    Parameters:

      - regaddr (`int`) – slave register address to write to

      - out (`Union`[`bytes`, `bytearray`, `Iterable`[`int`]]) – the byte buffer to send

      - relax (`bool`) – whether to relax the bus (emit STOP) or not

      - start (`bool`) – whether to emit a start sequence (w/ address)

    Raises:

      I2cIOError – if device is not configured or input parameters are invalid

class pyftdi.i2c.I2cGpioPort(controller)

  GPIO port

  A I2cGpioPort instance enables to drive GPIOs wich are not reserved for I2c feature as regular GPIOs.

  GPIO are managed as a bitfield. The LSBs are reserved for the I2c feature, which means that the lowest pin that can be used as a GPIO is b3:

  - b0: I2C SCL

  - b1: I2C SDA_O

  - b2: I2C SDA_I

  - b3: first GPIO

  - b7: reserved for I2C clock stretching, if this mode is enabled

  There is no offset bias in GPIO bit position, i.e. the first available GPIO can be reached from as `0x08`.

  Bitfield size depends on the FTDI device: 4432H series use 8-bit GPIO ports, while 232H and 2232H series use wide 16-bit ports.

  An I2cGpio port is never instanciated directly: use `I2cController.get_gpio()` method to obtain the GPIO port.

  property all_pins: int

    Report the addressable GPIOs as a bitfield.

    A true bit represents a pin which may be used as a GPIO, a false bit a reserved pin (for I2C support)

    Returns:

      the bitfield of configurable GPIO pins.

  property direction: int

    Provide the FTDI GPIO direction.self

    A true bit represents an output GPIO, a false bit an input GPIO.

    Returns:

      the bitfield of direction.

  property pins: int

    Report the configured GPIOs as a bitfield.

    A true bit represents a GPIO, a false bit a reserved or not configured pin.

    Returns:

      the bitfield of configured GPIO pins.

  read(with_output=False)

    Read GPIO port.

    Parameters:

      with_output (`bool`) – set to unmask output pins

    Return type:

      `int`

    Returns:

      the GPIO port pins as a bitfield

  set_direction(pins, direction)

    Change the direction of the GPIO pins.

    Parameters:

      - pins (`int`) – which GPIO pins should be reconfigured

      - direction (`int`) – direction bitfield (high level for output)

    Return type:

      `None`

  property width: int

    Report the FTDI count of addressable pins.

    Note that all pins, including reserved I2C ones, are reported.

    Returns:

      the count of IO pins (including I2C ones).

  write(value)

    Write GPIO port.

    Parameters:

      value (`int`) – the GPIO port pins as a bitfield

    Return type:

      `None`

class pyftdi.i2c.I2cController

  I2c master.

  An I2c master should be instanciated only once for each FTDI port that supports MPSSE (one or two ports, depending on the FTDI device).

  Once configured, `get_port()` should be invoked to obtain an I2c port for each I2c slave to drive. I2c port should handle all I/O requests for its associated HW slave.

  It is not recommended to use I2cController `read()`, `write()` or `exchange()` directly.

  - `SCK` should be connected to `A*BUS0`, and `A*BUS7` if clock stretching mode is enabled

  - `SDA` should be connected to `A*BUS1` and `A*BUS2`

  close(freeze=False)

    Close the FTDI interface.

    Parameters:

      freeze (`bool`) – if set, FTDI port is not reset to its default state on close.

    Return type:

      `None`

  configure(url, **kwargs)

    Configure the FTDI interface as a I2c master.

    Parameters:

      - url (`Union`[`str`, `Device`]) – FTDI URL string, such as `ftdi://ftdi:232h/1`

      - kwargs (`Mapping`[`str`, `Any`]) – options to configure the I2C bus

    Return type:

      `None`

    Accepted options:

    - `interface`: when URL is specifed as a USB device, the interface named argument can be used to select a specific port of the FTDI device, as an integer starting from 1.

    - `direction` a bitfield specifying the FTDI GPIO direction, where high level defines an output, and low level defines an input. Only useful to setup default IOs at start up, use `I2cGpioPort` to drive GPIOs. Note that pins reserved for I2C feature take precedence over any this setting.

    - `initial` a bitfield specifying the initial output value. Only useful to setup default IOs at start up, use `I2cGpioPort` to drive GPIOs.

    - `frequency` float value the I2C bus frequency in Hz

    - `clockstretching` boolean value to enable clockstreching. xD7 (GPIO7) pin should be connected back to xD0 (SCK)

    - `debug` to increase log verbosity, using MPSSE tracer

  property configured: bool

    Test whether the device has been properly configured.

    Returns:

      True if configured

  property direction: int

    Provide the FTDI pin direction

    A true bit represents an output pin, a false bit an input pin.

    Returns:

      the bitfield of direction.

  exchange(address, out, readlen=0, relax=True)

    Send a byte sequence to a remote slave followed with a read request of one or more bytes.

    This command is useful to tell the slave what data should be read out.

    Parameters:

      - address (`Optional`[`int`]) – the address on the I2C bus, or None to discard start

      - out (`Union`[`bytes`, `bytearray`, `Iterable`[`int`]]) – the byte buffer to send

      - readlen (`int`) – count of bytes to read out.

      - relax (`bool`) – whether to relax the bus (emit STOP) or not

    Return type:

      `bytearray`

    Returns:

      read bytes

    Raises:

      I2cIOError – if device is not configured or input parameters are invalid

    Address is a logical slave address (0x7f max)

  flush()

    Flush the HW FIFOs.

    Return type:

      `None`

  force_clock_mode(enable)

    Force unsupported I2C clock signalling on devices that have no I2C capabilities (i.e. FT2232D). I2cController cowardly refuses to use unsupported devices. When this mode is enabled, I2cController can drive such devices, but I2C signalling is not compliant with I2C specifications and may not work with most I2C slaves.

    `force_clock_mode()` should always be called before `configure()` to be effective.

    This is a fully unsupported feature (bug reports will be ignored).

    Parameters:

      enable (`bool`) – whether to drive non-I2C capable devices.

    Return type:

      `None`

  property frequency: float

    Provides the current I2C clock frequency in Hz.

    Returns:

      the I2C bus clock frequency

  property frequency_max: float

    Provides the maximum I2C clock frequency in Hz.

    Returns:

      I2C bus clock frequency

  property ftdi: Ftdi

    Return the Ftdi instance.

    Returns:

      the Ftdi instance

  get_gpio()

    Retrieve the GPIO port.

    Return type:

      `I2cGpioPort`

    Returns:

      GPIO port

  get_port(address)

    Obtain an I2cPort to drive an I2c slave.

    Parameters:

      address (`int`) – the address on the I2C bus

    Return type:

      `I2cPort`

    Returns:

      an I2cPort instance

  property gpio_all_pins: int

    Report the addressable GPIOs as a bitfield.

    A true bit represents a pin which may be used as a GPIO, a false bit a reserved pin (for I2C support)

    Returns:

      the bitfield of configurable GPIO pins.

  property gpio_pins: int

    Report the configured GPIOs as a bitfield.

    A true bit represents a GPIO, a false bit a reserved or not configured pin.

    Returns:

      the bitfield of configured GPIO pins.

  poll(address, write=False, relax=True)

    Poll a remote slave, expect ACK or NACK.

    Parameters:

      - address (`int`) – the address on the I2C bus, or None to discard start

      - write (`bool`) – poll in write mode (vs. read)

      - relax (`bool`) – whether to relax the bus (emit STOP) or not

    Return type:

      `bool`

    Returns:

      True if the slave acknowledged, False otherwise

  poll_cond(address, fmt, mask, value, count, relax=True)

    Poll a remove slave, watching for condition to satisfy. On each poll cycle, a repeated start condition is emitted, without releasing the I2C bus, and an ACK is returned to the slave.

    If relax is set, this method releases the I2C bus however it leaves.

    Parameters:

      - address (`int`) – the address on the I2C bus, or None to discard start

      - fmt (`str`) – struct format for poll register

      - mask (`int`) – binary mask to apply on the condition register before testing for the value

      - value (`int`) – value to test the masked condition register against. Condition is satisfied when register & mask == value

      - count (`int`) – maximum poll count before raising a timeout

      - relax (`bool`) – whether to relax the bus (emit STOP) or not

    Return type:

      `Optional`[`bytes`]

    Returns:

      the polled register value, or None if poll failed

  read(address, readlen=1, relax=True)

    Read one or more bytes from a remote slave

    Parameters:

      - address (`Optional`[`int`]) – the address on the I2C bus, or None to discard start

      - readlen (`int`) – count of bytes to read out.

      - relax (`bool`) – not used

    Return type:

      `bytes`

    Returns:

      read bytes

    Raises:

      I2cIOError – if device is not configured or input parameters are invalid

    Address is a logical slave address (0x7f max)

    Most I2C devices require a register address to read out check out the exchange() method.

  read_gpio(with_output=False)

    Read GPIO port.

    Parameters:

      with_output (`bool`) – set to unmask output pins

    Return type:

      `int`

    Returns:

      the GPIO port pins as a bitfield

  set_gpio_direction(pins, direction)

    Change the direction of the GPIO pins.

    Parameters:

      - pins (`int`) – which GPIO pins should be reconfigured

      - direction (`int`) – direction bitfield (on for output)

    Return type:

      `None`

  set_retry_count(count)

    Change the default retry count when a communication error occurs, before bailing out. :type count: `int` :param count: count of retries

    Return type:

      `None`

  terminate()

    Close the FTDI interface.

    Note:

      deprecated API, use close()

    Return type:

      `None`

  classmethod validate_address(address)

    Assert an I2C slave address is in the supported range. None is a special bypass address.

    Parameters:

      address (`Optional`[`int`]) – the address on the I2C bus

    Raises:

      I2cIOError – if the I2C slave address is not supported

    Return type:

      `None`

  property width: int

    Report the FTDI count of addressable pins.

    Returns:

      the count of IO pins (including I2C ones).

  write(address, out, relax=True)

    Write one or more bytes to a remote slave

    Parameters:

      - address (`Optional`[`int`]) – the address on the I2C bus, or None to discard start

      - out (`Union`[`bytes`, `bytearray`, `Iterable`[`int`]]) – the byte buffer to send

      - relax (`bool`) – whether to relax the bus (emit STOP) or not

    Raises:

      I2cIOError – if device is not configured or input parameters are invalid

    Return type:

      `None`

    Address is a logical slave address (0x7f max)

    Most I2C devices require a register address to write into. It should be added as the first (byte)s of the output buffer.

  write_gpio(value)

    Write GPIO port.

    Parameters:

      value (`int`) – the GPIO port pins as a bitfield

    Return type:

      `None`

## Exceptions

exception pyftdi.i2c.I2cIOError

  I2c I/O error

exception pyftdi.i2c.I2cNackError

  I2c NACK receive from slave

exception pyftdi.i2c.I2cTimeoutError

  I2c timeout on polling

## GPIOs

See GPIOs for details

## Tests

I2C sample tests expect:

  - TCA9555 device on slave address 0x21

  - ADXL345 device on slave address 0x53

Checkout a fresh copy from PyFtdi github repository.

See FTDI device pinout for FTDI wiring.

    # optional: specify an alternative FTDI device
    export FTDI_DEVICE=ftdi://ftdi:2232h/1
    # optional: increase log level
    export FTDI_LOGLEVEL=DEBUG
    # be sure to connect the appropriate I2C slaves to the FTDI I2C bus and run
    PYTHONPATH=. python3 pyftdi/tests/i2c.py

## Caveats

### Open-collector bus

I2C uses only two bidirectional open collector (or open drain) lines, pulled up with resistors. These resistors are also required on an I2C bus when an FTDI master is used.

However, most FTDI devices do not use open collector outputs. Some software tricks are used to fake open collector mode when possible, for example to sample for slave ACK/NACK, but most communication (R/W, addressing, data) cannot use open collector mode. This means that most FTDI devices source current to the SCL and SDA lines. FTDI HW is able to cope with conflicting signalling, where FTDI HW forces a line the high logical level while a slave forces it to the low logical level, and limits the sourced current. You may want to check your schematics if the slave is not able to handle 4 .. 16 mA input current in SCL and SDA, for example. The maximal source current depends on the FTDI device and the attached EEPROM configuration which may be used to limit further down the sourced current.

Fortunately, FT232H device is fitted with real open collector outputs, and PyFtdi always enable this mode on SCL and SDA lines when a FT232H device is used.

Other FTDI devices such as FT2232H, FT4232H and FT4232HA do not support open collector mode, and source current to SCL and SDA lines.

### Clock streching

Clock stretching is supported through a hack that re-uses the JTAG adaptative clock mode designed for ARM devices. FTDI HW drives SCL on `AD0` (BD0), and samples the SCL line on : the 8th pin of a port `AD7` (`BD7`).

When a FTDI device without an open collector capability is used (FT2232H, FT4232H, FT4232HA) the current sourced from AD0 may prevent proper sampling ofthe SCL line when the slave attempts to strech the clock. It is therefore recommended to add a low forward voltage drop diode to AD0 to prevent AD0 to source current to the SCL bus. See the wiring section.

### Speed

Due to the FTDI MPSSE engine limitations, the actual bitrate for write operations over I2C is very slow. As the I2C protocol enforces that each I2C exchanged byte needs to be acknowledged by the peer, a I2C byte cannot be written to the slave before the previous byte has been acknowledged by the slave and read back by the I2C master, that is the host. This requires several USB transfer for each byte, on top of each latency of the USB stack may add up. With the introduction of PyFtdi v0.51, read operations have been optimized so that long read operations are now much faster thanwith previous PyFtdi versions, and exhibits far shorter latencies.

Use of PyFtdi should nevetherless carefully studied and is not recommended if you need to achieve medium to high speed write operations with a slave (relative to the I2C clock…). Dedicated I2C master such as FT4222H device is likely a better option, but is not currently supported with PyFtdi as it uses a different communication protocol.

## Wiring

Fig.1: FT2232H with clock stretching

- `AD0` should be connected to the SCL bus

- `AD1` and `AD2` should be both connected to the SDA bus

- `AD7` should be connected to the SCL bus, if clock streching is required

- remaining pins can be freely used as regular GPIOs.

Fig.1:

- `D1` is only required when clock streching is used along with FT2232H, FT4232H or FT4232HA devices. It should not be fit with an FT232H.

- `AD7` may be used as a regular GPIO with clock stretching is not required.