i2c-controller

CLI reference

glasgow run i2c-controller

Initiate transactions on the I²C bus.

The following optional bus features are supported:

  • Clock stretching

  • Device ID

usage: glasgow run i2c-controller [-h] [-V SPEC] [--scl PIN] [--sda PIN]
                                  [-f FREQ]
                                  OPERATION ...
-h, --help

show this help message and exit

-V <spec>, --voltage <spec>

configure I/O port voltage to SPEC (e.g.: ‘3.3’, ‘A=5.0,B=3.3’, ‘A=SA’)

--scl <pin>

bind the applet I/O line ‘scl’ to PIN (default: ‘A0’, required)

--sda <pin>

bind the applet I/O line ‘sda’ to PIN (default: ‘A1’, required)

-f <freq>, --frequency <freq>

set SCL frequency to FREQ kHz (default: 100, range: 100…4000)

glasgow run i2c-controller scan

usage: glasgow run i2c-controller scan [-h] [--device-id]
-h, --help

show this help message and exit

--device-id

read device ID from devices responding to scan

API reference

exception glasgow.applet.interface.i2c_controller.I2CNotAcknowledged
class glasgow.applet.interface.i2c_controller.I2CControllerInterface(logger: Logger, assembly: AbstractAssembly, *, scl: GlasgowPin, sda: GlasgowPin)
property clock: ClockDivisor

SCL clock divisor.

transaction()

Perform a transaction.

While a transaction is active, calls to write() and read() do not generate a STOP condition; only one STOP condition is generated once the transaction ends. This also means that each call to write() or read() after the first such call in a transaction will generate a repeated START condition.

For example, to perform S 0x50 nW 0x01 A Sr 0x50 R 0x?? nA 0x?? P (read of two bytes from a 24-series single address byte EEPROM, starting at address 0x01), use the following code:

async with iface.transaction():
    await iface.write(0x50, [0x01])
    data = await iface.read(0x50, 2)

An empty transaction (where the body does not call write() or read()) is allowed and produces no bus activity. (A START condition followed by a STOP condition is prohibited by the I²C specification.)

async write(address: int, data: bytes | bytearray | memoryview)

Write bytes.

Generates a START condition followed by a WRITE target address ((address << 1) | 0), writes data, then generates a STOP condition (unless used within a transaction).

Raises:

I2CNotAcknowledged – If either the target address or the written data receives a not-acknowledgement.

async read(address: int, count: int) bytes

Read bytes.

Generates a START condition followed by a READ target address ((address << 1) | 1), reads data, then generates a STOP condition (unless used within a transaction).

The I²C bus design requires count to be 1 or more.

Raises:

I2CNotAcknowledged – If the target address receives a not-acknowledgement.

async ping(address: int) bool

Check address for presence.

Generates a START condition followed by a WRITE target address, then generates a STOP condition (unless used within a transaction). This is done using a write() call with no data.

Returns True if the target adddress receives an acknowledgement, False otherwise.

async scan(addresses: range = range(0b0001_000, 0b1111_000)) set[int]

Scan address range for presence.

Calls ping() for each of addresses. The default address range includes every non-reserved I²C address.

Returns the set of addresses receiving an acknowledgement.

async device_id(address: int) tuple[int, int, int]

Retrieve Device ID.

The standard I²C Device ID command (which uses the reserved address 0b1111_100) must not be confused with various vendor-specific device identifiers (which use a vendor-specific mechanism). This command is optional and rarely implemented.

Returns a 3-tuple (manufacturer, part_ident, revision).

Raises:

I2CNotAcknowledged – If the command is not implemented.