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

Detailed Description

Inter-Integrated Circuit driver interface.


The I2C header file should be included in an application as follows:

#include <ti/drivers/I2C.h>

This module serves as the main interface for applications using an underlying I2C peripheral. Its purpose is to redirect the I2C APIs to device specific driver implementations which are specified using a pointer to a I2C_FxnTable.

Overview

This section assumes that you have prior knowledge about the I2C protocol. For the full I2C-bus specification and user manual, view the UM10204 document available online.

This 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.

Thread Safety

This driver has been designed to operate with a Real-Time Operating System (RTOS). All I2C APIs are globally thread safe.

I2C Driver Configuration

In order to use the I2C APIs, the application is required to provide device-specific I2C configuration in the Board.c file. The I2C driver interface defines a configuration data structure, I2C_Config.

The application must declare an array of I2C_Config elements, named I2C_config[]. Each element of I2C_config[] is populated with pointers to a device specific I2C driver implementation's function table, driver object, and hardware attributes. The hardware attributes define properties such as the I2C peripheral's base address and pins. Each element in I2C_config[] corresponds to an I2C instance, and none of the elements should have NULL pointers.

The I2C configuration is device dependent. You will need to check the device specific I2C driver documentation. There you will find a description of the I2C hardware attributes.

Usage

For general usage, refer to the function documentation.

Initializing the I2C Driver

I2C_init() must be called before any other I2C API. This function calls the device specific implementation's I2C initialization function for each element of I2C_config[].

Opening the I2C Driver

After calling I2C_init(), the application can open an I2C instance by calling I2C_open(). This function takes an index into the I2C_config[] array and an I2C_Params structure. The I2C_Handle returned from the I2C_open() is then associated with that index into the I2C_config[] array. 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(Board_I2C0, NULL);
if (i2cHandle == NULL) {
// Error opening I2C
while (1) {}
}
Note
Each I2C index can only be opened exclusively. Calling I2C_open() multiple times with the same index will result in an error. The index can be re-used if I2C_close() is called first.

This example shows opening an I2C driver instance in I2C_MODE_CALLBACK with a bit rate of I2C_400kHz.

void myCallbackFxn(I2C_Handle handle, I2C_Transaction *msg, bool status)
{
if (status == false) {
//transfer failed
}
}
I2C_Handle i2cHandle;
I2C_Params i2cParams;
I2C_Params_init(&i2cParams);
i2cParams.transferCallbackFxn = myCallbackFxn;
i2cParams.bitRate = I2C_400kHz;
i2cHandle = I2C_open(Board_I2C0, &i2cParams);
if (i2cHandle == NULL) {
// Error opening I2C
while (1);
}

Transferring data

An I2C data transfer is performed using the I2C_transfer() function. Three types of transactions are supported: write, read, and write + read. The details of each transaction are specified with an I2C_Transaction structure. Each transfer is completed before another transfer is initiated.

For write + read transactions, the specified data is first written to the peripheral, then a repeated start is sent by the driver, which initiates the read operation. This type of transfer is useful if an I2C peripheral has a pointer register that needs to be adjusted prior to reading from the referenced data register.

The following examples assume an I2C instance has been opened in I2C_MODE_BLOCKING mode.


Sending three bytes of data.

I2C_Transaction i2cTransaction;
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
}

Reading five bytes of data.

I2C_Transaction i2cTransaction;
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) {
// Unsuccessful I2C transfer
}

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

I2C_Transaction i2cTransaction;
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) {
// Unsuccessful I2C transfer
}

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 (status == false) {
//transaction failed
}
// Check for a semaphore handle
if (msg->arg != NULL) {
// 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 callbackFxn posts the semaphore, the thread will be unblocked and can resume execution.

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

Implementation

This top-level I2C module serves as the main interface for RTOS applications. Its purpose is to redirect the module's APIs to specific peripheral implementations which are specified using a pointer to an I2C_FxnTable.

The I2C driver interface module is joined (at link time) to an array of I2C_Config data structures named I2C_config. I2C_config is typically defined in the Board.c file used for the application. If there are multiple instances of I2C peripherals on the device, there will typically be multiple I2C_Config structures defined in the board file in the form of an array. Each entry in I2C_config contains a:

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
Include dependency graph for I2C.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  I2C_Transaction_
 Structure used to perform I2C bus transfers. More...
 
struct  I2C_Params_
 I2C Parameters. More...
 
struct  I2C_FxnTable_
 The definition of an I2C function table that contains the required set of functions to control a specific I2C driver implementation. More...
 
struct  I2C_Config_
 I2C global configuration. More...
 

Macros

#define I2C_CMD_RESERVED   (32)
 
#define I2C_STATUS_RESERVED   (-32)
 
#define I2C_STATUS_SUCCESS   (0)
 Successful status code returned by I2C_control(). More...
 
#define I2C_STATUS_ERROR   (-1)
 Generic error status code returned by I2C_control(). More...
 
#define I2C_STATUS_UNDEFINEDCMD   (-2)
 An error status code returned by I2C_control() for undefined command codes. More...
 

Typedefs

typedef struct I2C_Config_I2C_Handle
 A handle that is returned from an I2C_open() call. More...
 
typedef struct I2C_Transaction_ I2C_Transaction
 Structure used to perform I2C bus transfers. More...
 
typedef enum I2C_TransferMode_ I2C_TransferMode
 Specifies the behavior of I2C_Transfer(). More...
 
typedef void(* I2C_CallbackFxn) (I2C_Handle handle, I2C_Transaction *transaction, bool transferStatus)
 I2C callback function prototype. More...
 
typedef enum I2C_BitRate_ I2C_BitRate
 Specifies the standard I2C bus bit rate. More...
 
typedef struct I2C_Params_ I2C_Params
 I2C Parameters. More...
 
typedef void(* I2C_CancelFxn) (I2C_Handle handle)
 A function pointer to a driver-specific implementation of I2C_cancel(). More...
 
typedef void(* I2C_CloseFxn) (I2C_Handle handle)
 A function pointer to a driver-specific implementation of I2C_close(). More...
 
typedef int_fast16_t(* I2C_ControlFxn) (I2C_Handle handle, uint_fast16_t cmd, void *controlArg)
 A function pointer to a driver-specific implementation of I2C_control(). More...
 
typedef void(* I2C_InitFxn) (I2C_Handle handle)
 A function pointer to a driver-specific implementation of I2C_init(). More...
 
typedef I2C_Handle(* I2C_OpenFxn) (I2C_Handle handle, I2C_Params *params)
 A function pointer to a driver-specific implementation of I2C_open(). More...
 
typedef bool(* I2C_TransferFxn) (I2C_Handle handle, I2C_Transaction *transaction)
 A function pointer to a driver-specific implementation of I2C_transfer(). More...
 
typedef struct I2C_FxnTable_ I2C_FxnTable
 The definition of an I2C function table that contains the required set of functions to control a specific I2C driver implementation. More...
 
typedef struct I2C_Config_ I2C_Config
 I2C global configuration. More...
 

Enumerations

enum  I2C_TransferMode_ { I2C_MODE_BLOCKING, I2C_MODE_CALLBACK }
 Specifies the behavior of I2C_Transfer(). More...
 
enum  I2C_BitRate_ {
  I2C_100kHz = 0, I2C_400kHz = 1, I2C_1000kHz = 2, I2C_3330kHz = 3,
  I2C_3400kHz = 3
}
 Specifies the standard I2C bus bit rate. More...
 

Functions

void I2C_cancel (I2C_Handle handle)
 Cancels all I2C transfers. More...
 
void I2C_close (I2C_Handle handle)
 Close an I2C driver instance specified by an I2C_Handle. More...
 
int_fast16_t I2C_control (I2C_Handle handle, uint_fast16_t cmd, void *controlArg)
 Perform implementation-specific features on a given I2C_Handle. More...
 
void I2C_init (void)
 Initializes the I2C module. More...
 
I2C_Handle I2C_open (uint_least8_t index, I2C_Params *params)
 Open an I2C instance. More...
 
void I2C_Params_init (I2C_Params *params)
 Initialize an I2C_Params structure to its default values. More...
 
bool I2C_transfer (I2C_Handle handle, I2C_Transaction *transaction)
 Perform an I2C transaction with an I2C slave peripheral. More...
 

Typedef Documentation

§ I2C_Handle

typedef struct I2C_Config_* I2C_Handle

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

§ I2C_Transaction

Structure used to perform I2C bus transfers.

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. This driver will always perform write operations first. Transmission of the I2C slave address with the appropriate read/write bit is handled internally by this driver.

Note
I2C_Transaction structures cannot be re-used until the previous transaction has completed.
See also
I2C_transfer()

§ I2C_TransferMode

Specifies the behavior of I2C_Transfer().

The I2C_TransferMode is specified using the I2C_Params.transferMode field.

§ I2C_CallbackFxn

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

I2C callback function prototype.

The application is responsible for declaring a callback function when I2C_Params.transferMode is I2C_MODE_CALLBACK. The callback function is specified using the I2C_Params.transferCallbackFxn parameter. The callback function will be called from either a hardware or software interrupt context.

Parameters
handleI2C_Handle to the I2C instance that called the I2C_transfer().
transactionPointer to the I2C_Transaction that just completed.
transferStatusBoolean indicating if the I2C transaction was successful. False indicates the transaction did not complete.

§ I2C_BitRate

typedef enum I2C_BitRate_ I2C_BitRate

Specifies the standard I2C bus bit rate.

The I2C_BitRate is specified using the I2C_Params.bitRate parameter. You must check that the device specific implementation supports the desired I2C_BitRate.

§ I2C_Params

typedef struct I2C_Params_ I2C_Params

I2C Parameters.

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

Note
The I2C_Params for a I2C_Handle cannot be changed after I2C_open() has been called. The I2C_Handle can be closed and re-opened with new parameters. See I2C_open() and I2C_close().
See also
I2C_open()
I2C_Params_init()

§ I2C_CancelFxn

typedef void(* I2C_CancelFxn) (I2C_Handle handle)

A function pointer to a driver-specific implementation of I2C_cancel().

§ I2C_CloseFxn

typedef void(* I2C_CloseFxn) (I2C_Handle handle)

A function pointer to a driver-specific implementation of I2C_close().

§ I2C_ControlFxn

typedef int_fast16_t(* I2C_ControlFxn) (I2C_Handle handle, uint_fast16_t cmd, void *controlArg)

A function pointer to a driver-specific implementation of I2C_control().

§ I2C_InitFxn

typedef void(* I2C_InitFxn) (I2C_Handle handle)

A function pointer to a driver-specific implementation of I2C_init().

§ I2C_OpenFxn

typedef I2C_Handle(* I2C_OpenFxn) (I2C_Handle handle, I2C_Params *params)

A function pointer to a driver-specific implementation of I2C_open().

§ I2C_TransferFxn

typedef bool(* I2C_TransferFxn) (I2C_Handle handle, I2C_Transaction *transaction)

A function pointer to a driver-specific implementation of I2C_transfer().

§ I2C_FxnTable

typedef struct I2C_FxnTable_ I2C_FxnTable

The definition of an I2C function table that contains the required set of functions to control a specific I2C driver implementation.

§ I2C_Config

typedef struct I2C_Config_ I2C_Config

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.

See also
I2C_init()

Enumeration Type Documentation

§ I2C_TransferMode_

Specifies the behavior of I2C_Transfer().

The I2C_TransferMode is specified using the I2C_Params.transferMode field.

Enumerator
I2C_MODE_BLOCKING 

In blocking mode, a thread calling I2C_transfer() is blocked until the I2C_Transaction completes. Other threads requesting I2C transactions 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 queued blocked transactions will not be executed in chronological order.

I2C_MODE_CALLBACK 

In callback mode, a thread calling I2C_transfer() is not blocked. The application's callback function, I2C_Params.transferCallbackFxn, is called when the transaction is complete. The callback function will be called from either a hardware or software interrupt context. This depends on the device specific driver implementation. 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 as each transaction is completed.

§ I2C_BitRate_

Specifies the standard I2C bus bit rate.

The I2C_BitRate is specified using the I2C_Params.bitRate parameter. 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, and is applicable only 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 the same context as the I2C_cancel().

Precondition
I2C_Transfer() has been called.
Parameters
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_close()

void I2C_close ( I2C_Handle  handle)

Close an I2C driver instance specified by an I2C_Handle.

Precondition
I2C_open() has been called.
Parameters
handleAn I2C_Handle returned from I2C_open()
See also
I2C_open()

§ I2C_control()

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

Perform implementation-specific features on a given I2C_Handle.

Commands for I2C_control() can originate from I2C.h or from device specific implementations files. While commands from I2C.h are API portable across driver implementations, not all implementations may support all these commands. Conversely, commands from driver implementation specific I2C*.h files add unique driver capabilities but are not API portable across all I2C driver implementations.

Commands supported by I2C.h follow a I2C_CMD_<cmd> naming convention.
Commands supported by I2C.h follow a I2C_CMD_<cmd> naming convention.
Each control command defines arg differently. The types of arg are documented with each command.

See I2C_control command codes for command codes.

See I2C_control return status codes for status codes.

Precondition
I2C_open() has to be called first.
Parameters
handleAn I2C_Handle returned from I2C_open()
cmdI2C_control command and status codes command.
controlArgAn optional R/W (read/write) command argument accompanied with cmd
Returns
Implementation-specific return codes. Negative values indicate unsuccessful operations.
See also
I2C_open()

§ I2C_init()

void I2C_init ( void  )

Initializes the I2C module.

Precondition
The I2C_config structure must exist and be persistent before this function can be called. This function must also be called before any other I2C driver APIs. This function call does not modify any peripheral registers.

§ I2C_open()

I2C_Handle I2C_open ( uint_least8_t  index,
I2C_Params params 
)

Open an I2C instance.

Initialize a given I2C driver instance as identified by an index value.

Precondition
I2C_init() has been called.
Parameters
indexIndexed into the I2C_config table
paramsPointer to a parameter block. Default values will be used if NULL is specified for params.
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
paramsA pointer to I2C_Params structure for initialization.

Defaults values are:

§ 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.

The data written to the peripheral is preceded with the peripheral's 7-bit I2C slave address (with the Write bit set). After all the data has been transmitted, the driver will evaluate if any data needs to be read from the device. If yes, another START bit is sent, along with the same 7-bit I2C slave address (with the Read bit). After the specified number of bytes have been read, the transfer is ended with a NACK and a STOP bit. Otherwise, if no data is to be read, the transfer is concluded with a STOP bit.

In I2C_MODE_BLOCKING, I2C_transfer() will block thread execution until the transaction completes. When using blocking mode, this function must be called from a thread context.

In I2C_MODE_CALLBACK, the I2C_transfer() call does not block thread execution. Success or failure of the transaction is reported via the I2C_CallbackFxn bool argument. If a transfer is already in progress, the new transaction is put on an internal queue. The driver services the queue in a first come first served basis. When using callback mode, this function can be called from any context.

Parameters
handleAn I2C_Handle
transactionA pointer to an I2C_Transaction. All of the fields within the transaction structure should be considered write only, unless otherwise noted in the driver implementation.
Note
The I2C_Transaction structure must persist unmodified until the corresponding call to I2C_transfer() has completed.
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.
See also
I2C_open()
© Copyright 1995-2018, Texas Instruments Incorporated. All rights reserved.
Trademarks | Privacy policy | Terms of use | Terms of sale