Data Structures | Macros | Typedefs | Enumerations | Functions | Variables
I2C.h File Reference

Detailed Description

Inter-Integrated Circuit (I2C) Driver.


Overview

The I2C driver is designed to operate as an I2C master and will not function as an I2C slave. Multi-master arbitration is not supported; therefore, this driver assumes it is the only I2C master on the bus. This I2C driver's API set provides the ability to transmit and receive data over an I2C bus between the I2C master and I2C slave(s). The application is responsible for manipulating and interpreting the data.


Usage

This section provides a basic usage summary and a set of examples in the form of commented code fragments. Detailed descriptions of the I2C APIs and their effect are provided in subsequent sections.

Synopsis

// Import I2C Driver definitions
#include <ti/drivers/I2C.h>
// Define name for an index of an I2C bus
#define SENSORS 0
// Define the slave address of device on the SENSORS bus
#define OPT_ADDR 0x47
// One-time init of I2C driver
// initialize optional I2C bus parameters
I2C_Params_init(&params);
// Open I2C bus for usage
I2C_Handle i2cHandle = I2C_open(SENSORS, &params);
// Initialize slave address of transaction
I2C_Transaction transaction = {0};
transaction.slaveAddress = OPT_ADDR;
// Read from I2C slave device
transaction.readBuf = data;
transaction.readCount = sizeof(data);
transaction.writeCount = 0;
I2C_transfer(i2cHandle, &transaction);
// Write to I2C slave device
transaction.writeBuf = command;
transaction.writeCount = sizeof(command);
transaction.readCount = 0;
I2C_transferTimeout(i2cHandle, &transaction, 5000);
// Close I2C
I2C_close(i2cHandle);

Examples

Opening the I2C Driver

After calling I2C_init(), the application can open an I2C instance by calling I2C_open().The following code example opens an I2C instance with default parameters by passing NULL for the I2C_Params argument.

I2C_Handle i2cHandle;
i2cHandle = I2C_open(0, NULL);
if (i2cHandle == NULL) {
// Error opening I2C
while (1) {}
}

Sending three bytes of data.

I2C_Transaction i2cTransaction = {0};
uint8_t writeBuffer[3];
writeBuffer[0] = 0xAB;
writeBuffer[1] = 0xCD;
writeBuffer[2] = 0xEF;
i2cTransaction.slaveAddress = 0x50;
i2cTransaction.writeBuf = writeBuffer;
i2cTransaction.writeCount = 3;
i2cTransaction.readBuf = NULL;
i2cTransaction.readCount = 0;
status = I2C_transfer(i2cHandle, &i2cTransaction);
if (status == false) {
// Unsuccessful I2C transfer
if (i2cTransaction.status == I2C_STATUS_ADDR_NACK) {
// I2C slave address not acknowledged
}
}

Reading five bytes of data.

I2C_Transaction i2cTransaction = {0};
uint8_t readBuffer[5];
i2cTransaction.slaveAddress = 0x50;
i2cTransaction.writeBuf = NULL;
i2cTransaction.writeCount = 0;
i2cTransaction.readBuf = readBuffer;
i2cTransaction.readCount = 5;
status = I2C_transfer(i2cHandle, &i2cTransaction);
if (status == false) {
if (i2cTransaction.status == I2C_STATUS_ADDR_NACK) {
// I2C slave address not acknowledged
}
}

Writing two bytes and reading four bytes in a single transaction.

I2C_Transaction i2cTransaction = {0};
uint8_t readBuffer[4];
uint8_t writeBuffer[2];
writeBuffer[0] = 0xAB;
writeBuffer[1] = 0xCD;
i2cTransaction.slaveAddress = 0x50;
i2cTransaction.writeBuf = writeBuffer;
i2cTransaction.writeCount = 2;
i2cTransaction.readBuf = readBuffer;
i2cTransaction.readCount = 4;
status = I2C_transfer(i2cHandle, &i2cTransaction);
if (status == false) {
if (i2cTransaction->status == I2C_STATUS_ADDR_NACK) {
// slave address not acknowledged
}
}

Using callback mode

This final example shows usage of I2C_MODE_CALLBACK, with queuing of multiple transactions. Because multiple transactions are simultaneously queued, separate I2C_Transaction structures must be used. Each I2C_Transaction will contain a custom application argument of a semaphore handle. The I2C_Transaction.arg will point to the semaphore handle. When the callback function is called, the I2C_Transaction.arg is checked for NULL. If this value is not NULL, then it can be assumed the arg is pointing to a valid semaphore handle. The semaphore handle is then used to call sem_post(). Hypothetically, this can be used to signal transaction completion to the task(s) that queued the transaction(s).

void callbackFxn(I2C_Handle handle, I2C_Transaction *msg, bool status)
{
// if transaction failed
if (status == false) {
// slave address not acknowledged
}
else if (msg->status == I2C_STATUS_CANCEL) {
// transaction canceled by I2C_cancel()
}
}
// Check for a custom argument
if (msg->arg != NULL) {
// In this example, the custom argument is a semaphore handle
// Perform a semaphore post
sem_post((sem_t *) (msg->arg));
}
}

Snippets of the thread code that initiates the transactions are shown below. Note the use of multiple I2C_Transaction structures. The handle of the semaphore to be posted is specified via i2cTransaction2.arg. I2C_transfer() is called three times to initiate each transaction. Since callback mode is used, these functions return immediately. After the transactions have been queued, other work can be done. Eventually, sem_wait() is called causing the thread to block until the transaction completes. When the transaction completes, the application's callback function, callbackFxn will be called. Once I2C_CallbackFxn posts the semaphore, the thread will be unblocked and can resume execution.

void thread(arg0, arg1)
{
I2C_Transaction i2cTransaction0 = {0};
I2C_Transaction i2cTransaction1 = {0};
I2C_Transaction i2cTransaction2 = {0};
// ...
i2cTransaction0.arg = NULL;
i2cTransaction1.arg = NULL;
i2cTransaction2.arg = semaphoreHandle;
// ...
I2C_transfer(i2c, &i2cTransaction0);
I2C_transfer(i2c, &i2cTransaction1);
I2C_transfer(i2c, &i2cTransaction2);
// ...
sem_wait(semaphoreHandle);
}

Configuration

Refer to the Driver's Configuration section for driver configuration information.


This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  I2C_Transaction
 Defines a transaction to be used with I2C_transfer() or I2C_transferTimeout() More...
 
struct  I2C_Params
 I2C parameters used with I2C_open(). More...
 
struct  I2C_Config_
 I2C driver's custom configuration structure. More...
 

Macros

#define I2C_STATUS_QUEUED   (1)
 I2C transaction is queued but has not started. More...
 
#define I2C_STATUS_SUCCESS   (0)
 Successful status code returned by I2C API. More...
 
#define I2C_STATUS_ERROR   (-1)
 Generic error status code returned by I2C API. More...
 
#define I2C_STATUS_UNDEFINEDCMD   (-2)
 An error status code returned by I2C_control() for undefined command codes. More...
 
#define I2C_STATUS_TIMEOUT   (-3)
 I2C operation timed-out. More...
 
#define I2C_STATUS_CLOCK_TIMEOUT   (-4)
 I2C serial clock line timeout. More...
 
#define I2C_STATUS_ADDR_NACK   (-5)
 I2C slave address not acknowledged. More...
 
#define I2C_STATUS_DATA_NACK   (-6)
 I2C data byte not acknowledged. More...
 
#define I2C_STATUS_ARB_LOST   (-7)
 I2C multi-master arbitration lost. More...
 
#define I2C_STATUS_INCOMPLETE   (-8)
 I2C transaction is in progress or returned without completing. More...
 
#define I2C_STATUS_BUS_BUSY   (-9)
 I2C bus already in use by another controller. The I2C transaction was therefore unable to start. More...
 
#define I2C_STATUS_CANCEL   (-10)
 I2C transaction canceled by I2C_cancel() More...
 
#define I2C_STATUS_INVALID_TRANS   (-11)
 I2C transaction is invalid. This may occur if: More...
 
#define I2C_WAIT_FOREVER   (~(0U))
 Wait forever define used to specify timeouts. More...
 

Typedefs

typedef struct I2C_Config_I2C_Handle
 A handle that is returned from an I2C_open() call. More...
 
typedef void(* I2C_CallbackFxn) (I2C_Handle handle, I2C_Transaction *transaction, bool transferStatus)
 The definition of a callback function. More...
 
typedef struct I2C_Config_ I2C_Config
 I2C driver's custom configuration structure. More...
 

Enumerations

enum  I2C_TransferMode { I2C_MODE_BLOCKING, I2C_MODE_CALLBACK }
 Return behavior of I2C_Transfer() specified in the I2C_Params. More...
 
enum  I2C_BitRate {
  I2C_100kHz = 0, I2C_400kHz = 1, I2C_1000kHz = 2, I2C_3330kHz = 3,
  I2C_3400kHz = 3
}
 Bit rate for an I2C driver instance specified in the I2C_Params. More...
 

Functions

void I2C_cancel (I2C_Handle handle)
 Cancels all I2C transfers. More...
 
void I2C_close (I2C_Handle handle)
 Function to close an I2C driver instance. More...
 
int_fast16_t I2C_control (I2C_Handle handle, uint_fast16_t cmd, void *controlArg)
 Function performs implementation specific features on a driver instance. More...
 
void I2C_init (void)
 Function to initialize the I2C driver. More...
 
I2C_Handle I2C_open (uint_least8_t index, I2C_Params *params)
 Open an I2C driver instance. More...
 
void I2C_Params_init (I2C_Params *params)
 Initialize an I2C_Params structure to its default values. More...
 
int_fast16_t I2C_setClockTimeout (I2C_Handle handle, uint32_t timeout)
 Set the I2C SCL clock timeout. More...
 
bool I2C_transfer (I2C_Handle handle, I2C_Transaction *transaction)
 Perform an I2C transaction with an I2C slave peripheral. More...
 
int_fast16_t I2C_transferTimeout (I2C_Handle handle, I2C_Transaction *transaction, uint32_t timeout)
 Perform an I2C transaction with an I2C slave peripheral. More...
 

Variables

const I2C_Config I2C_config []
 
const uint_least8_t I2C_count
 

Macro Definition Documentation

§ I2C_WAIT_FOREVER

#define I2C_WAIT_FOREVER   (~(0U))

Wait forever define used to specify timeouts.

Typedef Documentation

§ I2C_Handle

typedef struct I2C_Config_* I2C_Handle

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

§ I2C_CallbackFxn

typedef void(* I2C_CallbackFxn) (I2C_Handle handle, I2C_Transaction *transaction, bool transferStatus)

The definition of a callback function.

When operating in I2C_MODE_CALLBACK, the callback function is called when an I2C_transfer() completes. The application is responsible for declaring an I2C_CallbackFxn function and providing a pointer in I2C_Params.transferCallbackFxn.

Warning
The callback function is called from an interrupt context.
Parameters
[out]handleI2C_Handle used with the initial call to I2C_transfer()
[out]transactionPointer to the I2C_Transaction structure used with the initial call to I2C_transfer(). This structure contains the custom argument specified by transaction.arg and the transaction status.
[out]transferStatusBoolean indicating if the I2C transaction was successful. If true, the transaction was successful. If false, the transaction failed.

§ I2C_Config

typedef struct I2C_Config_ I2C_Config

I2C driver's custom configuration structure.

See also
I2C_init()
I2C_open()

Enumeration Type Documentation

§ I2C_TransferMode

Return behavior of I2C_Transfer() specified in the I2C_Params.

This enumeration defines the return behaviors for a call to I2C_transfer().

See also
I2C_Params
Enumerator
I2C_MODE_BLOCKING 

In I2C_MODE_BLOCKING, calls to I2C_transfer() block until the I2C_Transaction completes. Other threads calling I2C_transfer() while a transaction is in progress are also placed into a blocked state. If multiple threads are blocked, the thread with the highest priority will be unblocked first. This implies that arbitration will not be executed in chronological order.

Note
When using I2C_MODE_BLOCKING, I2C_transfer() must be called from a thread context.
I2C_MODE_CALLBACK 

In I2C_MODE_CALLBACK, calls to I2C_transfer() return immediately. The application's callback function, I2C_Params.transferCallbackFxn, is called when the transaction is complete. Sequential calls to I2C_transfer() will place I2C_Transaction structures into an internal queue. Queued transactions are automatically started after the previous transaction has completed. This queuing occurs regardless of any error state from previous transactions. The transactions are always executed in chronological order. The I2C_Params.transferCallbackFxn function will be called asynchronously as each transaction is completed.

§ I2C_BitRate

Bit rate for an I2C driver instance specified in the I2C_Params.

This enumeration defines the bit rates used with an I2C_transfer().

Note
You must check that the device specific implementation supports the desired I2C_BitRate.
Enumerator
I2C_100kHz 

I2C Standard-mode. Up to 100 kbit/s.

I2C_400kHz 

I2C Fast-mode. Up to 400 kbit/s.

I2C_1000kHz 

I2C Fast-mode Plus. Up to 1Mbit/s.

I2C_3330kHz 

I2C High-speed mode. Up to 3.4Mbit/s.

I2C_3400kHz 

I2C High-speed mode. Up to 3.4Mbit/s.

Function Documentation

§ I2C_cancel()

void I2C_cancel ( I2C_Handle  handle)

Cancels all I2C transfers.

This function will cancel asynchronous I2C_transfer() operations by generating a STOP condition on the I2C bus.

Calls to I2C_cancel() return immediately; however, the transaction may not yet be canceled.

For I2C_MODE_BLOCKING, the current transaction is canceled.

For I2C_MODE_CALLBACK mode, the in progress transfer, as well as any queued transfers, will be canceled. The individual callback functions for each transfer will be called in chronological order. The callback functions are called in an interrupt context. Additional calls to I2C_transfer() invoked from the callback function of a canceled transaction will always fail. In such cases, the I2C_Transaction.status will indicate I2C_STATUS_INVALID_TRANS.

A canceled transaction may be identified when the I2C_Transaction.status is set to I2C_STATUS_CANCEL.

Note
This API may not handle cases where the I2C slave holds the clock line indefinitely.
Precondition
I2C_Transfer() has been called.
Parameters
[in]handleAn I2C_Handle returned from I2C_open()
Note
Different I2C slave devices will behave differently when an in-progress transfer fails and needs to be canceled. The slave may need to be reset, or there may be other slave-specific steps that can be used to successfully resume communication.
See also
I2C_transfer()
I2C_MODE_CALLBACK

§ I2C_close()

void I2C_close ( I2C_Handle  handle)

Function to close an I2C driver instance.

Precondition
I2C_open() has been called.
Parameters
[in]handleAn I2C_Handle returned from I2C_open()

§ I2C_control()

int_fast16_t I2C_control ( I2C_Handle  handle,
uint_fast16_t  cmd,
void *  controlArg 
)

Function performs implementation specific features on a driver instance.

Precondition
I2C_open() has to be called first.
Parameters
[in]handleAn I2C_Handle returned from I2C_open()
[in]cmdA command value defined by the device specific implementation
[in]controlArgAn optional R/W (read/write) argument that is accompanied with cmd
Returns
Implementation specific return codes. Negative values indicate unsuccessful operations.
Return values
I2C_STATUS_SUCCESSThe call was successful.
I2C_STATUS_UNDEFINEDCMDThe cmd value is not supported by the device specific implementation.

§ I2C_init()

void I2C_init ( void  )

Function to initialize the I2C driver.

This function must also be called before any otherI2C driver APIs.

§ I2C_open()

I2C_Handle I2C_open ( uint_least8_t  index,
I2C_Params params 
)

Open an I2C driver instance.

Precondition
I2C_init() has been called.
Parameters
[in]indexIndex in the I2C_Config[] array.
[in]paramsPointer to an initialized I2C_Params structure. If NULL, the default I2C_Params values are used.
Returns
An I2C_Handle on success, or NULL on an error.
See also
I2C_init()
I2C_close()

§ I2C_Params_init()

void I2C_Params_init ( I2C_Params params)

Initialize an I2C_Params structure to its default values.

Parameters
[in]paramsA pointer to I2C_Params structure for initialization.

Defaults values are:

§ I2C_setClockTimeout()

int_fast16_t I2C_setClockTimeout ( I2C_Handle  handle,
uint32_t  timeout 
)

Set the I2C SCL clock timeout.

An I2C slave can extend a I2C transaction by periodically pulling the clock low to create a slow bit transfer rate. The application can use this API to program a counter in the I2C module. The count is used to force a timeout if an I2C slave holds the clock line low for longer than the timeout duration. An I2C_STATUS_CLOCK_TIMEOUT status indicates a timeout event occured.

Parameters
[in]handleAn I2C_Handle returned from I2C_open()
[in]timeoutTimeout in units of I2C clock cycles. Refer to the device specifc reference manual to determine how to calculate the timeout value.
Returns
Possible return values include:
See also
I2C_transfer()

§ I2C_transfer()

bool I2C_transfer ( I2C_Handle  handle,
I2C_Transaction transaction 
)

Perform an I2C transaction with an I2C slave peripheral.

This function will perform an I2C transfer, as specified by an I2C_Transaction structure.

Note
When using I2C_MODE_BLOCKING, this must be called from a thread context.
Parameters
[in]handleAn I2C_Handle returned from I2C_open()
[in]transactionA pointer to an I2C_Transaction. The application is responsible for allocating and initializing an I2C_Transaction structure prior to passing it to I2C_Transfer(). This structure must persist in memory unmodified until the transfer is complete.
Note
I2C_Transaction structures cannot be re-used until the previous transaction has completed. Upon the completion of a transaction, the I2C_Transaction.status may be used for error handling.
Returns
In I2C_MODE_BLOCKING: true for a successful transfer; false for an error (for example, an I2C bus fault (NACK)).
In I2C_MODE_CALLBACK: always true. The I2C_CallbackFxn bool argument will be true to indicate success, and false to indicate an error.
Precondition
I2C_open() has been called.
See also
I2C_open(), I2C_transferTimeout()
I2C_Transaction

§ I2C_transferTimeout()

int_fast16_t I2C_transferTimeout ( I2C_Handle  handle,
I2C_Transaction transaction,
uint32_t  timeout 
)

Perform an I2C transaction with an I2C slave peripheral.

This function will perform an I2C transfer, as specified by an I2C_Transaction structure. If the timeout is exceeded, then the I2C transaction is canceled.

Note
When using I2C_MODE_BLOCKING, this must be called from a thread context.
The timeout restriction is only applied when using I2C_MODE_BLOCKING. If using I2C_MODE_CALLBACK, the application should manage timeouts using I2C_cancel(). Additionally, this timeout may not handle cases where the I2C slave holds the clock line indefinitely.
Parameters
[in]handleAn I2C_Handle returned from I2C_open()
[in]transactionA pointer to an I2C_Transaction. The application is responsible for allocating and initializing an I2C_Transaction structure prior to passing it to I2C_TransferTimeout(). This structure must persist in memory unmodified until the transfer is complete.
[in]timeoutThe time in system ticks to wait for the transaction to complete. Passing I2C_WAIT_FOREVER into this parameter will cause I2C_transferTimeout() to behave the same as I2C_transfer() but with a more detailed return status.
Note
I2C_Transaction structures cannot be re-used until the previous transaction has completed. Upon the completion of a transaction, the I2C_Transaction.status may be used for error handling.
Returns
In I2C_MODE_CALLBACK: always I2C_STATUS_SUCCESS. The I2C_CallbackFxn transferStatus argument will be true to indicate success, and false to indicate an error.
In I2C_MODE_BLOCKING: Possible return values include:
Precondition
I2C_open() has been called.
See also
I2C_open(), I2C_transfer()
I2C_Transaction

Variable Documentation

§ I2C_config

const I2C_Config I2C_config[]

§ I2C_count

const uint_least8_t I2C_count
© Copyright 1995-2022, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale