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(¶ms);
params.transferMode = I2C_MODE_BLOCKING;
I2C_init();
gI2cHandle = I2C_open(CONFIG_I2C0, ¶ms);
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
- 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]
-
uint32_t baseAddr
-
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
-
uint32_t memAddr
-
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
-
void *writeBuf
-
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
-
uint8_t transferMode
-
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
-
SemaphoreP_Object mutex
-
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
-
I2C_Object *object