FreeRTOS: Common I/O
AWS IoT Common I/O library
Return to main page ↑
I2C Abstraction APIs.

Data Structures

struct  IotI2CConfig_t
 I2C bus configuration. More...
 

Macros

#define IOT_I2C_STANDARD_MODE_BPS   ( 100000 )
 
#define IOT_I2C_FAST_MODE_BPS   ( 400000 )
 
#define IOT_I2C_FAST_MODE_PLUS_BPS   ( 1000000 )
 
#define IOT_I2C_HIGH_SPEED_BPS   ( 3400000 )
 
#define IOT_I2C_SUCCESS   ( 0 )
 
#define IOT_I2C_INVALID_VALUE   ( 1 )
 
#define IOT_I2C_BUSY   ( 2 )
 
#define IOT_I2C_WRITE_FAILED   ( 3 )
 
#define IOT_I2C_READ_FAILED   ( 4 )
 
#define IOT_I2C_NACK   ( 5 )
 
#define IOT_I2C_BUS_TIMEOUT   ( 6 )
 
#define IOT_I2C_NOTHING_TO_CANCEL   ( 7 )
 
#define IOT_I2C_FUNCTION_NOT_SUPPORTED   ( 8 )
 
#define IOT_I2C_SLAVE_ADDRESS_NOT_SET   ( 9 )
 

Typedefs

typedef struct IotI2CDescriptor * IotI2CHandle_t
 IotI2CHandle_t is the handle type returned by calling iot_i2c_open(). This is initialized in open and returned to caller. The caller must pass this pointer to the rest of APIs.
 
typedef void(* IotI2CCallback_t) (IotI2COperationStatus_t xOpStatus, void *pvUserContext)
 The callback function for completion of I2C operation. More...
 

Enumerations

enum  IotI2CBusStatus_t { eI2CBusIdle = 0, eI2cBusBusy = IOT_I2C_BUSY }
 I2C Bus status. More...
 
enum  IotI2COperationStatus_t { eI2CCompleted = IOT_I2C_SUCCESS, eI2CDriverFailed, eI2CNackFromSlave = IOT_I2C_NACK, eI2CMasterTimeout = IOT_I2C_BUS_TIMEOUT }
 I2C operation status. More...
 
enum  IotI2CIoctlRequest_t {
  eI2CSendNoStopFlag, eI2CSetSlaveAddr, eI2CSetMasterConfig, eI2CGetMasterConfig,
  eI2CGetBusState, eI2CBusReset, eI2CGetTxNoOfbytes, eI2CGetRxNoOfbytes
}
 Ioctl request types. More...
 

Functions

IotI2CHandle_t iot_i2c_open (int32_t lI2CInstance)
 Initiates and reserves an I2C instance as master. More...
 
void iot_i2c_set_callback (IotI2CHandle_t const pxI2CPeripheral, IotI2CCallback_t xCallback, void *pvUserContext)
 Sets the application callback to be called on completion of an operation. More...
 
int32_t iot_i2c_read_sync (IotI2CHandle_t const pxI2CPeripheral, uint8_t *const pucBuffer, size_t xBytes)
 Starts the I2C master read operation in synchronous mode. More...
 
int32_t iot_i2c_write_sync (IotI2CHandle_t const pxI2CPeripheral, uint8_t *const pucBuffer, size_t xBytes)
 Starts the I2C master write operation in synchronous mode. More...
 
int32_t iot_i2c_read_async (IotI2CHandle_t const pxI2CPeripheral, uint8_t *const pucBuffer, size_t xBytes)
 Starts the I2C master read operation in asynchronous mode. More...
 
int32_t iot_i2c_write_async (IotI2CHandle_t const pxI2CPeripheral, uint8_t *const pucBuffer, size_t xBytes)
 Starts the I2C master write operation in asynchronous mode. More...
 
int32_t iot_i2c_ioctl (IotI2CHandle_t const pxI2CPeripheral, IotI2CIoctlRequest_t xI2CRequest, void *const pvBuffer)
 Configures the I2C master with user configuration. More...
 
int32_t iot_i2c_close (IotI2CHandle_t const pxI2CPeripheral)
 Stops the ongoing operation and de-initializes the I2C peripheral. More...
 
int32_t iot_i2c_cancel (IotI2CHandle_t const pxI2CPeripheral)
 This function is used to cancel the current operation in progress, if possible. More...
 

Detailed Description

Macro Definition Documentation

◆ IOT_I2C_STANDARD_MODE_BPS

#define IOT_I2C_STANDARD_MODE_BPS   ( 100000 )

The speeds supported by I2C bus.Standard mode bits per second.

◆ IOT_I2C_FAST_MODE_BPS

#define IOT_I2C_FAST_MODE_BPS   ( 400000 )

Fast mode bits per second.

◆ IOT_I2C_FAST_MODE_PLUS_BPS

#define IOT_I2C_FAST_MODE_PLUS_BPS   ( 1000000 )

Fast plus mode bits per second.

◆ IOT_I2C_HIGH_SPEED_BPS

#define IOT_I2C_HIGH_SPEED_BPS   ( 3400000 )

High speed mode bits per second.

◆ IOT_I2C_SUCCESS

#define IOT_I2C_SUCCESS   ( 0 )

The return codes for the functions in I2C.I2C operation completed successfully.

◆ IOT_I2C_INVALID_VALUE

#define IOT_I2C_INVALID_VALUE   ( 1 )

At least one parameter is invalid.

◆ IOT_I2C_BUSY

#define IOT_I2C_BUSY   ( 2 )

I2C bus is busy at current time.

◆ IOT_I2C_WRITE_FAILED

#define IOT_I2C_WRITE_FAILED   ( 3 )

I2C driver returns error when performing write operation.

◆ IOT_I2C_READ_FAILED

#define IOT_I2C_READ_FAILED   ( 4 )

I2C driver returns error when performing read operation.

◆ IOT_I2C_NACK

#define IOT_I2C_NACK   ( 5 )

Unexpected NACK is caught.

◆ IOT_I2C_BUS_TIMEOUT

#define IOT_I2C_BUS_TIMEOUT   ( 6 )

I2C operation not completed within specified timeout.

◆ IOT_I2C_NOTHING_TO_CANCEL

#define IOT_I2C_NOTHING_TO_CANCEL   ( 7 )

No ongoing transaction when cancel operation is performed.

◆ IOT_I2C_FUNCTION_NOT_SUPPORTED

#define IOT_I2C_FUNCTION_NOT_SUPPORTED   ( 8 )

I2C operation is not supported.

◆ IOT_I2C_SLAVE_ADDRESS_NOT_SET

#define IOT_I2C_SLAVE_ADDRESS_NOT_SET   ( 9 )

Slave address is not set before calling I2C read or write operation.

Typedef Documentation

◆ IotI2CCallback_t

typedef void(* IotI2CCallback_t) (IotI2COperationStatus_t xOpStatus, void *pvUserContext)

The callback function for completion of I2C operation.

Parameters
[out]xOpStatusI2C asynchronous operation status.
[in]pvUserContextUser Context passed when setting the callback. This is not used or modified by the driver. The context is provided by the caller when setting the callback, and is passed back to the caller in the callback.

Enumeration Type Documentation

◆ IotI2CBusStatus_t

I2C Bus status.

Enumerator
eI2CBusIdle 

I2C bus is idle.

eI2cBusBusy 

I2C bus is busy.

◆ IotI2COperationStatus_t

I2C operation status.

Enumerator
eI2CCompleted 

I2C operation completed successfully.

eI2CDriverFailed 

I2C driver returns error during last operation.

eI2CNackFromSlave 

Unexpected NACK is caught.

eI2CMasterTimeout 

I2C operation not completed within specified timeout.

◆ IotI2CIoctlRequest_t

Ioctl request types.

Enumerator
eI2CSendNoStopFlag 

! Set flag to not send stop after transaction ! Default is always stop for every transaction ! Flag will auto reset to stop after one transaction if you set no stop

eI2CSetSlaveAddr 

! This can be either 7-bit address or 10-bit address. All the operations use this slave address after it is set.

eI2CSetMasterConfig 

! Sets the I2C bus frequency and timeout using the struct IotI2CConfig_t, default speed is Standard mode.

eI2CGetMasterConfig 

! Gets the I2C bus frequency and timeout set for the I2C master.

eI2CGetBusState 

! Get the current I2C bus status. Returns eI2CBusIdle or eI2CBusy

eI2CBusReset 

! Master resets the bus.

eI2CGetTxNoOfbytes 

! Get the number of bytes sent in write operation.

eI2CGetRxNoOfbytes 

! Get the number of bytes received in read operation.

Function Documentation

◆ iot_i2c_open()

IotI2CHandle_t iot_i2c_open ( int32_t  lI2CInstance)

Initiates and reserves an I2C instance as master.

One instance can communicate with one or more slave devices. Slave addresses need to be changed between actions to different slave devices.

Warning
Once opened, the same I2C instance must be closed before calling open again.
Parameters
[in]lI2CInstanceThe instance of I2C to initialize. This is between 0 and the number of I2C instances on board - 1.
Returns
  • 'the handle to the I2C port (not NULL)', on success.
  • 'NULL', if
    • invalid instance number
    • open same instance more than once before closing it

◆ iot_i2c_set_callback()

void iot_i2c_set_callback ( IotI2CHandle_t const  pxI2CPeripheral,
IotI2CCallback_t  xCallback,
void *  pvUserContext 
)

Sets the application callback to be called on completion of an operation.

The callback is guaranteed to be invoked when the current asynchronous operation completes, either successful or failed. This simply provides a notification mechanism to user's application. It has no impact if the callback is not set.

Note
This callback will not be invoked when synchronous operation completes.
This callback is per handle. Each instance has its own callback.
Single callback is used for both read_async and write_async. Newly set callback overrides the one previously set.
Warning
If the input handle is invalid, this function silently takes no action.
Parameters
[in]pxI2CPeripheralThe I2C peripheral handle returned in the open() call.
[in]xCallbackThe callback function to be called on completion of transaction.
[in]pvUserContextThe user context to be passed back when callback is called.

◆ iot_i2c_read_sync()

int32_t iot_i2c_read_sync ( IotI2CHandle_t const  pxI2CPeripheral,
uint8_t *const  pucBuffer,
size_t  xBytes 
)

Starts the I2C master read operation in synchronous mode.

This function attempts to read certain number of bytes from slave device to a pre-allocated buffer, in synchronous way. Partial read might happen, e.g. no more data is available. And the number of bytes that have been actually read can be obtained by calling iot_i2c_ioctl.

Note
Usually, the address of register needs to be written before calling this function.
If eI2CSendNoStopFlag is set and this function returns, whether the actual transaction has been started is undefined. This is board-specific behavior.
Warning
Prior to this function, slave address must be already configured.
None of other read or write functions shall be called during this function.
Parameters
[in]pxI2CPeripheralThe I2C handle returned in open() call.
[out]pucBufferThe receive buffer to read the data into. It must stay allocated before this function returns.
[in]xBytesThe number of bytes to read.
Returns
  • IOT_I2C_SUCCESS, on success (all the requested bytes have been read)
  • IOT_I2C_INVALID_VALUE, if
    • pxI2CPeripheral is NULL
    • pxI2CPeripheral is not opened yet
    • pucBuffer is NULL
    • xBytes is 0
  • IOT_I2C_SLAVE_ADDRESS_NOT_SET, if slave address is not set yet
  • IOT_I2C_NACK or IOT_I2C_READ_FAILED, if
    • no device correspond to the slave address
    • the slave is unable to receive or transmit
    • the slave gets data or commands that it does not understand
    • there is some unknown driver error
  • IOT_I2C_BUS_TIMEOUT, if timeout is supported and slave device does not respond within configured timeout.
  • IOT_I2C_BUSY, if the bus is busy which means there is an ongoing transaction.

Example

// Declare an I2C handle.
IotI2CHandle_t xI2CHandle;
// Return value of I2C functions.
int32_t lRetVal = IOT_I2C_SUCCESS;
// Register address on I2C slave device.
uint8_t xDeviceRegisterAddress = 0x73;
// Number of read/write bytes.
uint16_t usReadBytes = 0;
uint16_t usWriteBytes = 0;
uint8_t ucReadBuffer[2] = {0};
// Configurations of I2C master device.
IotI2CConfig_t xI2CConfig =
{
.ulMasterTimeout = 500
};
// Open one of the I2C instance and get a handle.
xI2CHandle = iot_i2c_open( 1 );
if ( xI2CHandle != NULL )
{
// Set I2C configuration.
lRetVal = iot_i2c_ioctl( xI2CHandle, eI2CSetMasterConfig, &xI2CConfig );
// assert(lRetVal == IOT_I2C_SUCCESS);
// Set slave address.
lRetVal = iot_i2c_ioctl( xI2CHandle, eI2CSetSlaveAddr, &uctestIotI2CSlaveAddr );
// assert(lRetVal == IOT_I2C_SUCCESS);
// Write the register address as single byte, in a transaction.
lRetVal = iot_i2c_write_sync( xI2CHandle, &xDeviceRegisterAddress, sizeof( xDeviceRegisterAddress ) );
if ( lRetVal == IOT_I2C_SUCCESS )
{
// Get the number of written bytes in last transaction.
lRetVal = iot_i2c_ioctl( xI2CHandle, eI2CGetTxNoOfbytes, &usWriteBytes );
// assert(lRetVal == IOT_I2C_SUCCESS);
// assert(usWriteBytes == 1);
// Read two bytes of data to allocated buffer, in a transaction.
lRetVal = iot_i2c_read_sync( xI2CHandle, &ucReadBuffer, sizeof( ucReadBuffer ) );
if ( lRetVal == IOT_I2C_SUCCESS )
{
// Get the number of read bytes in last transaction.
lRetVal = iot_i2c_ioctl( xI2CHandle, eI2CGetRxNoOfbytes, &usReadBytes );
// assert(lRetVal == IOT_I2C_SUCCESS);
// assert(usReadBytes == 2);
}
}
lRetVal = iot_i2c_close( xI2CHandle );
// assert(lRetVal == IOT_I2C_SUCCESS);
}

◆ iot_i2c_write_sync()

int32_t iot_i2c_write_sync ( IotI2CHandle_t const  pxI2CPeripheral,
uint8_t *const  pucBuffer,
size_t  xBytes 
)

Starts the I2C master write operation in synchronous mode.

This function attempts to write certain number of bytes from a pre-allocated buffer to a slave device, in synchronous way. Partial write might happen, e.g. slave device unable to receive more data. And the number of bytes that have been actually written can be obtained by calling iot_i2c_ioctl.

Note
Usually, the first byte is treated as the register address and the following bytes are treated as data to be written.
If eI2CSendNoStopFlag is set and this function returns, whether the actual transaction has been started is undefined. This is board-specific behavior.
Warning
Prior to this function, slave address must be already configured.
None of other read or write functions shall be called during this function.
Parameters
[in]pxI2CPeripheralThe I2C handle returned in open() call.
[in]pucBufferThe transmit buffer containing the data to be written. It must stay allocated before this function returns.
[in]xBytesThe number of bytes to write.
Returns
  • IOT_I2C_SUCCESS, on success (all the requested bytes have been written)
  • IOT_I2C_INVALID_VALUE, if
    • pxI2CPeripheral is NULL
    • pxI2CPeripheral is not opened yet
    • pucBuffer is NULL
    • xBytes is 0
  • IOT_I2C_SLAVE_ADDRESS_NOT_SET, if slave address is not set yet
  • IOT_I2C_NACK or IOT_I2C_WRITE_FAILED, if
    • no device correspond to the slave address
    • the slave is unable to receive or transmit
    • the slave gets data or commands that it does not understand
    • there is some unknown driver error
  • IOT_I2C_BUS_TIMEOUT, if timeout is supported and slave device does not respond within configured timeout.
  • IOT_I2C_BUSY, if the bus is busy which means there is an ongoing transaction.

◆ iot_i2c_read_async()

int32_t iot_i2c_read_async ( IotI2CHandle_t const  pxI2CPeripheral,
uint8_t *const  pucBuffer,
size_t  xBytes 
)

Starts the I2C master read operation in asynchronous mode.

This function attempts to read certain number of bytes from a pre-allocated buffer, in asynchronous way. It returns immediately when the operation is started and the status can be check by calling iot_i2c_ioctl. Once the operation completes, successful or not, the user callback will be invoked.

Partial read might happen, e.g. slave device unable to receive more data. And the number of bytes that have been actually read can be obtained by calling iot_i2c_ioctl.

Note
Usually, the address of register needs to be written before calling this function.
If eI2CSendNoStopFlag is set and this function returns, whether the actual transaction has been started is undefined. This is board-specific behavior.
In order to get notification when the asynchronous call is completed, iot_i2c_set_callback must be called prior to this.
Warning
Prior to this function, slave address must be already configured.
pucBuffer must be valid before callback is invoked.
None of other read or write functions shall be called during this function or before user callback.
Parameters
[in]pxI2CPeripheralThe I2C handle returned in open() call.
[out]pucBufferThe receive buffer to read the data into
[in]xBytesThe number of bytes to read.
Returns
  • IOT_I2C_SUCCESS, on success
  • IOT_I2C_INVALID_VALUE, if
    • pxI2CPeripheral is NULL
    • pxI2CPeripheral is not opened yet
    • pucBuffer is NULL
    • xBytes is 0
  • IOT_I2C_SLAVE_ADDRESS_NOT_SET, if slave address is not set yet
  • IOT_I2C_NACK or IOT_I2C_READ_FAILED, if
    • no device correspond to the slave address
    • the slave is unable to receive or transmit
    • the slave gets data or commands that it does not understand
    • there is some unknown driver error

◆ iot_i2c_write_async()

int32_t iot_i2c_write_async ( IotI2CHandle_t const  pxI2CPeripheral,
uint8_t *const  pucBuffer,
size_t  xBytes 
)

Starts the I2C master write operation in asynchronous mode.

This function attempts to write certain number of bytes from a pre-allocated buffer to a slave device, in asynchronous way. It returns immediately when the operation is started and the status can be check by calling iot_i2c_ioctl. Once the operation completes, successful or not, the user callback will be invoked.

Partial write might happen, e.g. slave device unable to receive more data. And the number of bytes that have been actually written can be obtained by calling iot_i2c_ioctl.

Note
Usually, the first byte is treated as the register address and the following bytes are treated as data to be written.
If eI2CSendNoStopFlag is set and this function returns, whether the actual transaction has been started is undefined. This is board-specific behavior.
In order to get notification when the asynchronous call is completed, iot_i2c_set_callback must be called prior to this.
Warning
Prior to this function, slave address must be already configured.
None of other read or write functions shall be called during this function.
Parameters
[in]pxI2CPeripheralThe I2C handle returned in open() call.
[in]pucBufferThe transmit buffer containing the data to be written. It must stay allocated before this function returns.
[in]xBytesThe number of bytes to write.
Returns
  • IOT_I2C_SUCCESS, on success
  • IOT_I2C_INVALID_VALUE, if
    • pxI2CPeripheral is NULL
    • pxI2CPeripheral is not opened yet
    • pucBuffer is NULL
    • xBytes is 0
  • IOT_I2C_SLAVE_ADDRESS_NOT_SET, if slave address is not set yet
  • IOT_I2C_NACK or IOT_I2C_WRITE_FAILED, if
    • no device correspond to the slave address
    • the slave is unable to receive or transmit
    • the slave gets data or commands that it does not understand
    • there is some unknown driver error
  • IOT_I2C_BUS_TIMEOUT, if timeout is supported and slave device does not respond within configured timeout.
  • IOT_I2C_BUSY, if the bus is busy which means there is an ongoing transaction.

◆ iot_i2c_ioctl()

int32_t iot_i2c_ioctl ( IotI2CHandle_t const  pxI2CPeripheral,
IotI2CIoctlRequest_t  xI2CRequest,
void *const  pvBuffer 
)

Configures the I2C master with user configuration.

Parameters
[in]pxI2CPeripheralThe I2C handle returned in open() call.
[in]xI2CRequestShould be one of I2C_Ioctl_Request_t.
[in,out]pvBufferThe configuration values for the IOCTL request.
Note
SetMasterConfig is expected only called once at beginning. This request expects the buffer with size of IotI2CConfig_t.
eI2CGetMasterConfig gets the current configuration for I2C master. This request expects the buffer with size of IotI2CConfig_t.
eI2CGetBusState gets the current bus state. This request expects buffer with size of IotI2CBusStatus_t.
eI2CSendNoStopFlag is called at every operation you want to not send stop condition.
eI2CSetSlaveAddr sets either 7-bit address or 10-bit address, according to hardware's capability. This request expects 2 bytes buffer (uint16_t)
eI2CGetTxNoOfbytes returns the number of written bytes in last transaction. This is supposed to be called in the caller task or application callback, right after last transaction completes. This request expects 2 bytes buffer (uint16_t).
  • If the last transaction only did write, this returns the actual number of written bytes which might be smaller than the requested number (partial write).
  • If the last transaction only did read, this returns 0.
  • If the last transaction did both write and read, this returns the number of written bytes.
Note
eI2CGetRxNoOfbytes returns the number of read bytes in last transaction. This is supposed to be called in the caller task or application callback, right after last transaction completes. This request expects 2 bytes buffer (uint16_t).
  • If the last transaction only did read, this returns the actual number of read bytes which might be smaller than the requested number (partial read).
  • If the last transaction only did write, this returns 0.
  • If the last transaction did both write and read, this returns the number of read bytes.
Returns
  • IOT_I2C_SUCCESS, on success
  • IOT_I2C_INVALID_VALUE, if
    • pxI2CPeripheral is NULL
    • pxI2CPeripheral is not opened yet
    • pucBuffer is NULL with requests which needs buffer
  • IOT_I2C_FUNCTION_NOT_SUPPORTED, if this board doesn't support this feature.
    • eI2CSetSlaveAddr: 10-bit address is not supported
    • eI2CSendNoStopFlag: explicitly not sending stop condition is not supported
    • eI2CBusReset: reset bus is not supported

◆ iot_i2c_close()

int32_t iot_i2c_close ( IotI2CHandle_t const  pxI2CPeripheral)

Stops the ongoing operation and de-initializes the I2C peripheral.

Parameters
[in]pxI2CPeripheralThe I2C handle returned in open() call.
Returns
  • IOT_I2C_SUCCESS, on success
  • IOT_I2C_INVALID_VALUE, if
    • pxI2CPeripheral is NULL
    • pxI2CPeripheral is not opened yet

◆ iot_i2c_cancel()

int32_t iot_i2c_cancel ( IotI2CHandle_t const  pxI2CPeripheral)

This function is used to cancel the current operation in progress, if possible.

Parameters
[in]pxI2CPeripheralThe I2C handle returned in open() call.
Returns
  • IOT_I2C_SUCCESS, on success
  • IOT_I2C_INVALID_VALUE, if
    • pxI2CPeripheral is NULL
    • pxI2CPeripheral is not opened yet
  • IOT_I2C_NOTHING_TO_CANCEL, if there is no on-going transaction.
  • IOT_I2C_FUNCTION_NOT_SUPPORTED, if this board doesn't support this operation.