View Source grisp_i2c (grisp v2.8.0)

GRiSP I²C API.

Inter-Integrated Circuit (I²C) is a synchronous addressable serial communication bus. Two types of nodes can exist, controllers and targets. Multiple controllers and targets can exist on the bus simultaneously. Controllers generate the clock signal and initiate communication with targets. Targets follow the clock and respond when addressed. A GRiSP board acts as a controller to any connected target peripherals on the I²C buses.

In GRiSP there are two main I²C buses, one "internal" bus (i2c0) and one "external" bus (i2c1). The internal bus talks to targets on the SoM and the board itself, such as EEPROM memory or the 1-Wire controller. The external bus talks to any connected target peripherals, either on the PMOD connector or the raised I²C pins.

Communication consists of either read or write messages. A read or write must be addressed to a specific target (chip). A target is addressed by a 7-bit address. The registry to use is specified in a target specific way. E.g. to read a register, some targets expect a write message with the register address as a value, followed by a read message.

Note

Please refer to the specification for a specific target chip for instructions of what messages to send and receive, and how the registers are structured.

Summary

Functions

Lists I²C buses.

Detects I²C devices on a bus.

Opens an I²C bus device by name.

Performs a simplified read from a register on an I²C chip.

Transfers I²C messages on a bus.

Performs a simplified write to a register on an I²C chip.

Types

bus()

-opaque bus()

bus_name()

-type bus_name() :: atom().

bus_path()

-type bus_path() :: iodata().

error()

-type error() :: {error, any()}.

length()

-type length() :: non_neg_integer().

message()

-type message() ::
          {Type :: read | write,
           Target :: target_addr(),
           Flags :: non_neg_integer(),
           Payload :: iodata() | length()}.

reg_addr()

-type reg_addr() :: byte().

target_addr()

-type target_addr() :: 1..127.

Functions

buses()

-spec buses() -> #{bus_name() := #{name := bus_name(), path := bus_path()}}.

Lists I²C buses.

Example

1> grisp_i2c:buses()
#{i2c0 => #{name => i2c0,path => <<"/dev/i2c-0">>},
  i2c1 => #{name => i2c1,path => <<"/dev/i2c-1">>}}

detect(Bus)

-spec detect(bus()) -> [target_addr()].

Detects I²C devices on a bus.

Returns the address of each found device.

Example

3> [io_lib:format("0x~.16B", [Target]) || Target <- grisp_i2c:detect(I2C0)].
["0x18","0x36","0x37","0x52","0x57","0x5A","0x5F"]

open(Name)

-spec open(bus_name()) -> bus().

Opens an I²C bus device by name.

Example

2> I2C0 = grisp_i2c:open(i2c1).
#Ref<0.4157010815.3886678017.238942>

read(Bus, Target, Register, Length)

-spec read(bus(), target_addr(), reg_addr(), length()) -> binary().

Performs a simplified read from a register on an I²C chip.

This function sends a write message with the single byte register address as value, then a read message of the specified length.

Note

Only some chips support this simple operation. Please consult the target chip specification.

Example

4> grisp_i2c:read(I2C1, TargetAddr, RegAddr, 1).
<<255>>

transfer(Bus, Messages)

-spec transfer(bus(), [message()]) -> [ok | binary()] | error().

Transfers I²C messages on a bus.

Examples

6> grisp_i2c:transfer(I2C1, [{read, TargetAddr, RegAddr, 1}])
[<<255>>]
7> grisp_i2c:transfer(I2C1, [{write, TargetAddr, RegAddr, <<Value:8>>}])
ok

write(Bus, Target, Register, Data)

-spec write(bus(), target_addr(), reg_addr(), binary()) -> ok.

Performs a simplified write to a register on an I²C chip.

This function sends a write message with the single byte register address as the first byte and then the data as the following bytes.

Note

Only some chips support this simple operation. Please consult the target chip specification.

Example

5> grisp_i2c:write(I2C1, TargetAddr, RegAddr, <<Value:8>>).
ok