Features Supported
- Controller and Target mode of Operation.
- Interrupt, Polled Mode.
- Non-blocking (Callback) Transfer.
- 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 parameters like bitrate, Own target address.
- 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
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 may call the following APIs:
Initializing the I2C LLD Driver
I2C_lld_init() must be called before any other I2C APIs. 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. Though, handle can be re-used the instance is closed using I2C_lld_deInit().
Please note that the initialization of I2C LLD instances 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 files to access the APIs
#include <kernel/dpl/MutexArmP.h>
#include <kernel/nortos/dpl/r5/HwiP_armv7r_vim.h>
Instance Open Example
gI2cLldHandle0 = (
I2CLLD_Handle)(&gI2cLldObjects[CONFIG_I2CLLD0]);
Instance Close Example
Non-Blocking Transfer Example
uint8_t wrData[2U];
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);
gI2cLldHandle0->transferCompleteCallback = I2C_lld_transferCompleteCallback_implementation;
HwiP_setVecAddr(intrNum, (uintptr_t)&App_I2C_ISR);
HwiP_setPri(intrNum, I2C_INTERRUPT_PRIORITY);
wrData[0U] = TPIC2810_CMD_WR_IMMEDIATE;
wrData[1U] = (uint8_t) (LED_SET_ALL);
i2cMsg.txn = &i2cTransaction;
i2cMsg.txnCount = 1U;
gI2CTransferMutex = MUTEX_ARM_LOCKED;
while(try_lock_mutex(&gI2CTransferMutex) == MUTEX_ARM_LOCKED);
{
}
HwiP_setVecAddr(intrNum, 0);
{
}
else
{
}
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)
{
gI2cLldHandle0, \
intrNum, \
gI2cVimStsAddr, \
gI2cVimStsClrMask,
intcBaseAddr);
}
API
APIs for I2C LLD