I2C

I2C module provides an interface to any I2C bus compatible device accessible via I2C serial bus. External components attached to I2C bus can serially transmit/receive data to/from the CPU through two wire interface. I2C driver provides API to perform transmit/receive to any of the I2C peripherals on the board, with the multiple modes of operation.

Features Supported

  • Master and Slave mode of operation

  • Interrupt, Polled Mode

  • Blocking and Non-blocking (callback) transfers

  • Queueing of I2C transactions

  • I2C Bus Recovery

SysConfig Features

Note

It is strongly recommend to use SysConfig where it is available instead of using direct SW API calls. This will help simplify the SW application and also catch common mistakes early in the development cycle.

SysConfig can be used to configure below parameters apart from common configuration like Clock,MPU,RAT and others.

  • I2C module configuration parmaters like bitrate, slave addresses to probe.

  • I2C instances and pin configurations.

  • Interrupt mode enable option.If you disable it, configures to polling mode.

  • Based on above parameters, the SysConfig generated code does below as part of Drivers_open and Drivers_close functions

    • Set I2C instance parameter configuration.

    • Driver ISR registration if Interrupt Mode is enabled.

Features NOT Supported

  • Slave mode is not supported in polling mode.

Failure Prevention Guidelines for Applications

Application developer must take care of the following guidelines to avoid failures:

  • The application developer should verify the bit rate supported by the end connected device while configuring the bit rate in the application.

  • The application developer should verify the pinmux settings in the syscfg and make sure that the correct pins are configured.

  • The application developer should verify that the correct addressing mode as supported by the end device is configured.

  • The application developer should make sure that suffecient buffers are allocated before starting the transaction.

  • The application developer should have bus recovery mechanisms for different operation modes of I2C like interrupt callback mode.

  • The application developer should make sure that there is no resource/memory conflict when using i2c in a multi-core use case

Important Usage Guidelines

J20 header pins needs to be shorted for having the write protect disabled for the EEPROM

Timeout

The I2C driver uses SystemP_WAIT_FOREVER (0xFFFFFFFFU) as the default timeout for blocking transfers.

Configurable Timeout

The transfer timeout is configurable per-transaction via the timeout field in I2C_Transaction, as shown below:

I2C_Transaction txn;
I2C_Transaction_init(&txn);   /* default: txn.timeout = SystemP_WAIT_FOREVER */
txn.timeout = 1000;           /* override: 1000 OS ticks */

When to change: Set a finite timeout in applications that require fault detection or cannot hang indefinitely if the I2C bus stalls due to a misbehaving slave or bus contention.

Note

A timeout value of 0 is not supported and is internally treated as SystemP_WAIT_FOREVER.

Non-Configurable Timeouts

The following operations always use SystemP_WAIT_FOREVER and cannot be overridden by the application:

  • Internal driver lock — A mutex protecting driver state, acquired at the start of every transfer. This waits forever if another transfer is already in progress on the same instance.

  • Bus busy check — Verifies the I2C bus is free before starting a transfer. This waits forever if the bus is permanently stuck busy (e.g., due to a hardware fault or missing pull-ups).

Example Usage

Include the below file to access the APIs

#include <drivers/i2c.h>

Instance Open Example

    I2C_Params      params;
  
    I2C_Params_init(&params);
    params.transferMode  = I2C_MODE_BLOCKING;
    I2C_init();
    gI2cHandle = I2C_open(CONFIG_I2C0, &params);
    if (!gI2cHandle) {
        DebugP_assert(FALSE);
    }

Instance Close Example

    I2C_close(gI2cHandle);

I2c Transfer Example

    int32_t status;

    I2C_Transaction i2cTransaction;
    I2C_Transaction_init(&i2cTransaction);
  
    i2cTransaction.writeBuf = txBuffer;
    i2cTransaction.writeCount = 1U;
  
    i2cTransaction.readBuf = rxBuffer;
    i2cTransaction.readCount = 2U;
  
    status = I2C_transfer(gI2cHandle, &i2cTransaction);
    if (SystemP_SUCCESS != status) {
        DebugP_assert(FALSE);
    }

API Reference

MACROS used to select the transfer mode

I2C_MODE_BLOCKING block task execution while a I2C transfer is in progress I2C_MODE_CALLBACK does not block task execution; but calls a callback function when the I2C transfer has completed

I2C_MODE_BLOCKING
I2C_MODE_CALLBACK

MACROS for the possible values of I2C_Mem_Transaction member

memDataDir. Deafults to I2C_TXN_DIR_INVALID

I2C_MEM_TXN_DIR_INVALID

I2C LLD invalid dataDir.

I2C_MEM_TXN_DIR_TX

I2C LLD Write.

I2C_MEM_TXN_DIR_RX

I2C LLD Read.

Defines

I2C_MAX_NUM_OWN_TARGET_ADDR

Typedefs

typedef struct I2C_Config_s *I2C_Handle

A handle that is returned from a I2C_open() call.

typedef void (*I2C_CallbackFxn)(I2C_Handle handle, I2C_Transaction *msg, int32_t transferStatus)

I2C callback function.

User definable callback function prototype. The I2C driver will call the defined function and pass in the I2C driver’s handle, the pointer to the I2C transaction that just completed, and the return value of I2C_transfer.

In target mode, when there is a restart condtion,the driver calls back to the application with received data and I2C_STS_RESTART transfer status, application needs to provide the restart transmit data in I2C_Transaction rsWrToMstBuf. Restart condition only works in callback mode.

Param handle:

I2C_Handle

Param msg:

Address of the I2C_Transaction performed

Param transferStatus:

Results of the I2C transaction

Functions

void I2C_init(void)

Initialize the I2C module.

void I2C_deinit(void)

De-nitialize the I2C module.

void I2C_Params_init(I2C_Params *params)

Function to set default values of I2C_Params in params.

Parameters:

params – [IN] pointer to the structure to be initialized

I2C_Handle I2C_open(uint32_t idx, const I2C_Params *params)

Open the I2C at index idx with parameters params.

Parameters:
  • idx – [IN] Index of I2C to open in global config

  • params – [IN] I2C_Params values to use for opening

Returns:

I2C_Handle

void I2C_close(I2C_Handle handle)

Function to close the I2C Peripheral specified by the handle.

See also

I2C_open()

Parameters:

handle – [IN] I2C_Handle returned from I2C_open()

Pre:

I2C_open() has to be called first

void I2C_Memory_Transaction_init(I2C_Mem_Transaction *memTransaction)

Function to set default values of I2C_Mem_Transaction in memTransaction.

Parameters:

memTransaction – [IN] pointer to the structure to be initialized

void I2C_Transaction_init(I2C_Transaction *transaction)

Function to set default values of I2C_Transaction in transaction.

Parameters:

transaction – [IN] pointer to the structure to be initialized

int32_t I2C_transfer(I2C_Handle handle, I2C_Transaction *transaction)

Function to initiate a transfer from I2C.

Parameters:
  • handle – [IN] handle to the I2C

  • transaction – [IN] I2C_Transaction structure that contains values for this specific transfer

Returns:

I2C_StatusCode

int32_t I2C_probe(I2C_Handle handle, uint32_t targetAddr)

Function to probe I2C.

Parameters:
  • handle – [IN] handle to the I2C

  • targetAddr – [IN] address of the target to probe

Returns:

I2C_StatusCode

int32_t I2C_setBusFrequency(I2C_Handle handle, uint32_t busFrequency)

Function to set the bus frequency.

Parameters:
  • handle – [IN] handle to the I2C

  • busFrequency – [IN] frequency value to be set

Returns:

I2C_StatusCode

int32_t I2C_recoverBus(I2C_Handle handle, uint32_t i2cDelay)

Function to recover the bus in case of error.

Parameters:
  • handle – [IN] handle to the I2C

  • i2cDelay – [IN] the length of delay for sending clock pulses to target

Returns:

I2C_StatusCode

I2C_Handle I2C_getHandle(uint32_t instIdx)

This function returns the handle of an open I2C instance from the instance index.

Parameters:

instIdx – [IN] Index of config to use in the I2C_Config array

Pre:

I2C controller has been opened using I2C_open()

Returns:

An I2C_Handle if it has been opened already or NULL otherwise

struct I2C_HwAttrs
#include <i2c.h>

I2C Hardware attributes.

Public Members

uint32_t baseAddr

I2C Peripheral base address

uint32_t intNum

I2C Peripheral interrupt vector

uint32_t eventId

I2C Peripheral event id

uint32_t funcClk

I2C input functional clock

bool enableIntr

enable Interrupt

uint8_t intrPriority

Interrupt Priority

uint32_t ownTargetAddr[I2C_MAX_NUM_OWN_TARGET_ADDR]

I2C own target addresses for multi-target channels, if only one target channel is supported, set the target address to ownTargetAddr[0]

struct I2C_Mem_Transaction
#include <i2c.h>

I2C Memory Transaction.

This structure stores parameters related to I2C memory transaction.

Public Members

uint32_t memAddr

[IN] Memory address to write to or read from

uint8_t memAddrSize

[IN] Memory address size I2CLLD_MemoryAddrSize

uint8_t *buffer

[IN] Pointer to Read or Write buffer

uint32_t size

[IN] Size of Read or Write buffer

uint8_t memDataDir

[IN] Target internal memory data direction I2C_memTransactionDir

struct I2C_Transaction
#include <i2c.h>

I2C transaction.

This structure defines the nature of the I2C transaction.

I2C controller mode: This structure specifies the buffer and buffer’s size that is to be written to or read from the I2C target peripheral.

I2C target mode: This structure specifies the buffer and buffer’s size that is to be read from or written to the I2C controller. In restart condition, readBuf/writeBuf and readCount/writeCount are used repeatedly for every start in one transfer. When each restart happens, driver will call back to application with the restart transfer status, and application should save the data transferred in the previous start, and provide the new data to the current start. When all the starts complete (stop condition), driver will call back to application with transfer success status, and readBuf/writeBuf and readCount/writeCount will only record the data transferred in the last start condition.

Public Members

void *writeBuf

controller mode: buffer containing data to be written to target target mode: buffer containing data to be written to controller

size_t writeCount

controller mode: number of bytes to be written to the target target mode: number of bytes to be written to the controller

void *readBuf

controller mode: buffer to which data from target is to be read into target mode: buffer to which data from controller is to be read into

size_t readCount

controller mode: number of bytes to be read from the target target mode: number of bytes to be read to the controller

uint32_t targetAddress

controller mode: input field from user to set the address of I2C target target mode: output field from driver to report the address of a target channel when multi-target channels are supported, if only one channel is supported, this field is ignored

void *nextPtr

used for queuing in I2C_MODE_CALLBACK mode

void *arg

used for passing argument to callback function

uint32_t timeout

Timeout value for i2c transaction

bool controllerMode

I2C controller or target mode

bool expandSA

Expand target address: true: 10-bit address mode, false: 7-bit address mode

bool memTxnEnable

Transaction type: true: Memory read/write Operation, false: Simple read and write operation

I2C_Mem_Transaction *memTransaction

Memory Transfer related Parameters

int32_t status

Transaction Status

struct I2C_Params
#include <i2c.h>

I2C Parameters.

I2C parameters are used to with the I2C_open() call. Default values for these parameters are set using I2C_Params_init().

If I2C_TransferMode is set to I2C_MODE_BLOCKING then I2C_transfer function calls will block thread execution until the transaction has completed.

If I2C_TransferMode is set to I2C_MODE_CALLBACK then I2C_transfer will not block thread execution and it will call the function specified by transferCallbackFxn. Sequential calls to I2C_transfer in I2C_MODE_CALLBACK mode will put the designated transaction onto an internal queue that automatically starts queued transactions after the previous transaction has completed. (regardless of error state).

I2cBitRates specifies the I2C bus rate used for I2C communications.

Public Members

uint8_t transferMode

Blocking or Callback mode

void (*transferCallbackFxn)(I2C_Handle i2cHnd, I2C_Transaction *msg, int32_t transferStatus)

I2C_CallbackFxn transferCallbackFxn; Callback function pointer

uint8_t bitRate

I2C bus bit rate

struct I2C_Object
#include <i2c.h>

I2C Object.

The application must not access any member variables of this structure!

Public Members

SemaphoreP_Object mutex

Grants exclusive access to I2C

SemaphoreP_Object transferComplete

Notify finished I2C transfer

HwiP_Object hwiObj

Hwi object

I2C_Params i2cParams

I2C open parameters as provided by user

uint8_t state

Stores the I2C state

I2C_Transaction *currentTransaction

I2C transaction variables Pointer to current I2C transaction

I2C_Transaction *headPtr
I2C_Transaction *tailPtr
bool isOpen
uint32_t intStatusErr
I2CLLD_Object i2cLldObject
I2CLLD_Handle i2cLldHandle
struct I2C_Config
#include <i2c.h>

I2C Global configuration.

The I2C_Config structure contains a set of pointers used to characterize the I2C driver implementation.

This structure needs to be defined before calling I2C_init() and it must not be changed thereafter.

Public Members

I2C_Object *object

Pointer to a driver specific data object

I2C_HwAttrs *hwAttrs

Pointer to a driver specific hardware attributes structure