AM273x MCU+ SDK  09.02.00
I2C Low Level Driver

Features Supported

  • Controller and Target mode of operation
  • Interrupt, Polled Mode
  • Non-blocking (callback) transfers
  • 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, target addresses to probe.
  • I2C instances and pin configurations.
  • Based on above parameters, the SysConfig generated code does below as part of Drivers_open and Drivers_close functions
    • Set I2C instance parameter configuration.

Features NOT Supported

  • Target mode is not supported in polling mode.

Usage Overview

API Sequence

To use the I2C LLD driver to transmit/receive data over the I2C bus, probe target and set bus frequency the application calls the following APIs:

Initializing the I2C LLD Driver

I2C_lld_init() must be called before any other I2C APIs. This function iterates till the channel count. This function uses i2c lld handle to initialize each instance.

Calling I2C_lld_init() a second time with the same handle previously passed to I2C_lld_init() will result in an error. You can, though, re-use the handle if the instance is closed via I2C_lld_deInit().

Please note that initializing I2C LLD driver is taken care by the SysConfig generated code.

I2C Transfer Mode

The I2C driver supports two transfer modes of operation: Polling and Interrupt Mode.

In Polling mode transfer can be initiated with all the polling mode APIs

In Interrupt mode Users have to register the appropriate ISR and assign a callback function before calling the interrupt mode APIs

Example Usage

Include the below file to access the APIs

#include <kernel/dpl/MutexArmP.h>
#include <kernel/nortos/dpl/r5/HwiP_armv7r_vim.h>

Instance Open Example

int32_t status = I2C_STS_SUCCESS;
gI2cLldHandle0 = (I2CLLD_Handle)(&gI2cLldObjects[CONFIG_I2CLLD0]);
status = I2C_lld_init(gI2cLldHandle0);

Instance Close Example

int32_t status = I2C_STS_SUCCESS;
status = I2C_lld_deInit(gI2cLldHandle0);

Non-Blocking Transfer Example

int32_t status = I2C_STS_SUCCESS;
uint8_t wrData[2U];
/* Interrupt configuration and registration*/
intrNum = gI2cLldHandle0->intrNum;
gI2cLldHandle0 = (I2CLLD_Handle)(&gI2cLldObjects[CONFIG_I2CLLD0]);
intrNum = gI2cLldHandle0->intrNum;
intcBaseAddr = gHwiConfig.intcBaseAddr;
gI2cVimStsAddr = intcBaseAddr + (0x404u + (((intrNum)>> 5) & 0xFu) * 0x20u);
gI2cVimStsClrMask = 0x1u << ((intrNum) & 0x1Fu);
DebugP_log("I2C LED Blink Test Started ...\r\n");
/* Assign Transfer Complete Callback Function */
gI2cLldHandle0->transferCompleteCallback = I2C_lld_transferCompleteCallback_implementation;
/* Register Interrupt */
HwiP_setVecAddr(intrNum, (uintptr_t)&App_I2C_ISR);
HwiP_setPri(intrNum, I2C_INTERRUPT_PRIORITY);
HwiP_enableInt(intrNum);
/* Set mask */
wrData[0U] = TPIC2810_CMD_WR_IMMEDIATE;
wrData[1U] = (uint8_t) (LED_SET_ALL);
/* Initialize transaction object */
I2C_lld_Transaction_init(&i2cTransaction);
i2cTransaction.writeBuf = &wrData[0U];
i2cTransaction.writeCount = 2U;
/* Initialize message object */
i2cMsg.txn = &i2cTransaction;
i2cMsg.txnCount = 1U;
i2cMsg.targetAddress = deviceAddress;
/* Lock Mutex */
gI2CTransferMutex = MUTEX_ARM_LOCKED;
/* Start Transfer in interrupt Mode */
status = I2C_lld_transferIntr(gI2cLldHandle0, &i2cMsg);
/* Wait for the Mutex to Unlock */
while(try_lock_mutex(&gI2CTransferMutex) == MUTEX_ARM_LOCKED);
if(I2C_STS_SUCCESS != status)
{
DebugP_assert(FALSE); /* I2C transfer failed!! */
}
/* Deregister IRQ */
HwiP_setVecAddr(intrNum, 0);
HwiP_disableInt(intrNum);
if(I2C_STS_SUCCESS == status)
{
DebugP_log("All tests have passed!!\r\n");
}
else
{
DebugP_log("Some tests have failed!!\r\n");
}

Non-Blocking Example transfer callback

void I2C_lld_transferCompleteCallback_implementation(void * args, const I2CLLD_Message * msg, int32_t transferStatus)
{
unlock_mutex(&gI2CTransferMutex);
}

Non-Blocking Example ISR CALL callback

static __attribute__((__section__(".text.hwi"), noinline, naked, target("arm"), aligned(4))) void App_I2C_ISR(void)
{
ISR_CALL_LEVEL_NONFLOAT_REENTRANT(I2C_lld_controllerIsr, \
gI2cLldHandle0, \
intrNum, \
gI2cVimStsAddr, \
gI2cVimStsClrMask,
intcBaseAddr);
}

API

APIs for I2C LLD

args
void * args
Definition: hsmclient_msg.h:4
I2C_lld_Transaction_init
int32_t I2C_lld_Transaction_init(I2CLLD_Transaction *transaction)
API to set default values of I2CLLD_Transaction in transaction.
I2C_lld_Message_init
int32_t I2C_lld_Message_init(I2CLLD_Message *msg)
API to set default values of I2CLLD_Message in msg.
i2c_lld.h
I2C LLD Driver API/interface file.
HwiP_disableInt
uint32_t HwiP_disableInt(uint32_t intNum)
Disable a specific interrupt.
I2C_Transaction::writeBuf
const void * writeBuf
Definition: i2c.h:233
I2CLLD_Message
I2C Message.
Definition: i2c_lld.h:220
I2C_Transaction::targetAddress
uint32_t targetAddress
Definition: i2c.h:247
DebugP_log
#define DebugP_log(format,...)
Function to log a string to the enabled console.
Definition: DebugP.h:225
HwiP.h
HwiP_enableInt
void HwiP_enableInt(uint32_t intNum)
Enable a specific interrupt.
I2C_lld_transferIntr
int32_t I2C_lld_transferIntr(I2CLLD_Handle handle, I2CLLD_Message *msg)
Function to initiate a transfer from I2C in interrupt mode.
I2C_lld_init
int32_t I2C_lld_init(I2CLLD_Handle handle)
This API Initializes the I2C instance.
DebugP.h
I2C_Transaction::writeCount
size_t writeCount
Definition: i2c.h:236
I2C_lld_controllerIsr
void I2C_lld_controllerIsr(void *args)
This is the I2C Controller ISR and can be used as IRQ handler in Controller mode.
DebugP_assert
#define DebugP_assert(expression)
Function to call for assert check.
Definition: DebugP.h:177
I2C_STS_SUCCESS
#define I2C_STS_SUCCESS
Return status when the API execution was successful.
Definition: i2c_lld.h:84
__attribute__
struct sockaddr __attribute__
HSM client / server message format struct.
I2C_lld_deInit
int32_t I2C_lld_deInit(I2CLLD_Handle handle)
This API De-Initializes the I2C instance.
I2CLLD_Handle
struct I2CLLD_Object * I2CLLD_Handle