How to perform the I2C transfer with I2CSPM driver
08/235/2018 | 09:55 AM
The I2C module on EFM32 and EFR32 devices provide an interface between the MCU and a serial I2C-bus. It is capable of acting as both a master and a slave and supports multi-master buses. Silabs provided examples project via SDK or Github to demonstrate both master and slave configurations of the EFM32/EFR32 I2C peripheral.
And also a higher level kit driver I2CSPM (I2C simple poll-based master mode driver) provided with a set of APIs for easily initializing the I2C peripheral as master mode and performing the I2C transfer, this KBA provides a step by step guide for how to extend the I2C master mode functionality with your project.
Please follow the steps below on how to perform the I2C transfer with the I2CSPM driver.
1. Create your project in Simplicity Studio.
2. Copy the i2cspm.c and i2cspm.h from the \hardware\kit\common\drivers folder in the SDK to your project.
3. Include the header file "i2cspm.h" to your project file.
4. Initialize the I2C peripheral as master mode with the API I2CSPM_Init().
5. Define the I2C Master mode transfer sequence which depends on the required I2C transfer.
6. Perform the I2C transfer with the API I2CSPM_Transfer().
The enclosed example project for EFM32PG12 demonstrates how to perform a one byte I2C read transfer, also the code snippet posted here for a quick overview. The parameter "addr" represents I2C slave address.
It supports 7-bit or 10-bit I2C address, the value of the "addr" here should be the I2C slave address with one bit left shifted. For example, if you need to communicate with the I2C slave addressed 0x29, the value of "addr" should be 0x52.
static I2C_TransferReturn_TypeDef i2cReadByte(I2C_TypeDef *i2c, uint16_t addr, uint8_t command, uint8_t *val)
{
I2C_TransferSeq_TypeDef seq;
I2C_TransferReturn_TypeDef sta;
uint8_t i2c_write_data[1];
uint8_t i2c_read_data[1];
seq.addr = addr;
seq.flags = I2C_FLAG_WRITE_READ;
/* Select command to issue */
i2c_write_data[0] = command;
seq.buf[0].data = i2c_write_data;
seq.buf[0].len = 1;
/* Select location/length of data to be read */
seq.buf[1].data = i2c_read_data;
seq.buf[1].len = 1;
sta = I2CSPM_Transfer(i2c, &seq);
if (sta != i2cTransferDone)
{
return sta;
}
if (NULL != val)
{
*val = i2c_read_data[0];
}
return sta;
}
As shown in the screenshot below, EFM32PG12 writes a command 0x20 to the Slave device and then read back one byte.
Note: In the GPIO module of the EFM32 the internal pull-up resistors have been enabled, hence external pull-up resistors are not necessary to make the example work. However, external resistors are generally preferable as they keep the lines defined at all times.
How does the github examples work in i2c slave mode?
performI2Ctransfer() calls I2C_Transfer() in em_i2c.c, and if you read the comment at the top of I2C_Transfer() it says "only single master mode supported". Reading the code this seems to be true.
Is there anywhere an i2c receive and transfer function for use in slave mode?
How to perform the I2C transfer with I2CSPM driver
The I2C module on EFM32 and EFR32 devices provide an interface between the MCU and a serial I2C-bus. It is capable of acting as both a master and a slave and supports multi-master buses. Silabs provided examples project via SDK or Github to demonstrate both master and slave configurations of the EFM32/EFR32 I2C peripheral.
And also a higher level kit driver I2CSPM (I2C simple poll-based master mode driver) provided with a set of APIs for easily initializing the I2C peripheral as master mode and performing the I2C transfer, this KBA provides a step by step guide for how to extend the I2C master mode functionality with your project.
Please follow the steps below on how to perform the I2C transfer with the I2CSPM driver.
1. Create your project in Simplicity Studio.
2. Copy the i2cspm.c and i2cspm.h from the \hardware\kit\common\drivers folder in the SDK to your project.
3. Include the header file "i2cspm.h" to your project file.
4. Initialize the I2C peripheral as master mode with the API I2CSPM_Init().
5. Define the I2C Master mode transfer sequence which depends on the required I2C transfer.
6. Perform the I2C transfer with the API I2CSPM_Transfer().
The enclosed example project for EFM32PG12 demonstrates how to perform a one byte I2C read transfer, also the code snippet posted here for a quick overview. The parameter "addr" represents I2C slave address.
It supports 7-bit or 10-bit I2C address, the value of the "addr" here should be the I2C slave address with one bit left shifted. For example, if you need to communicate with the I2C slave addressed 0x29, the value of "addr" should be 0x52.
As shown in the screenshot below, EFM32PG12 writes a command 0x20 to the Slave device and then read back one byte.
Get more information about the I2CSPM from the online documentation here:
http://devtools.silabs.com/dl/documentation/doxygen/5.5/efm32pg12/html/group__I2CSPM.html
Note: In the GPIO module of the EFM32 the internal pull-up resistors have been enabled, hence external pull-up resistors are not necessary to make the example work. However, external resistors are generally preferable as they keep the lines defined at all times.
How does the github examples work in i2c slave mode?
performI2Ctransfer() calls I2C_Transfer() in em_i2c.c, and if you read the comment at the top of I2C_Transfer() it says "only single master mode supported". Reading the code this seems to be true.
Is there anywhere an i2c receive and transfer function for use in slave mode?