I2C

I2C Demo Code Support List

This chapter introduces the details of the I2C demo code.

I2C Demo for Interrupt Mode

The description of I2C demo code 1 is shown in the following table.

I2C Demo Code 1 Description

Demo 1

i2c_demo.c

Sample Purpose

Demonstrate how I2C writes and reads data in interrupt mode.

Brief Introduction

This sample code demonstrates the communication between the chip and I2C slave. The chip writes some data to I2C slave and then chip reads data from I2C slave.

File Path

sdk\src\sample\io_demo\i2c\interrupt\i2c_demo.c

Function Entry

i2c_demo()

Hardware Connection

As shown in I2C Demo Code 1/2/3 Hardware Connection Diagram. On EVB, connect P0_0 to the SCL of the I2C slave, connect P0_1 to the SDA of the I2C slave.

I2C SCL Pin Definition

#define PIN_I2C0_SCL P0_0

I2C SDA Pin Definition

#define PIN_I2C0_SDA P0_1

I2C ID

I2C0

Clock Speed

100000

Device Mode

Master

Address Mode

7-Bit

Slave Address

0x50

ACK

ACK Enable

Expected Result

  1. Press the Reset button on the EVB, the I2C slave will receive data 0xaa and 0xbb, and the chip will receive four bytes from the I2C slave.

  2. When the I2C transmission ends, the string i2c0_handler: I2C0 stop detect will be displayed in the Debug Analyzer.

The hardware connection of I2C demo code 1 is shown in the figure below.

../../../_images/I2C_Demo_1_2_3_Hardware_Connection_Diagram.png

I2C Demo Code 1/2/3 Hardware Connection Diagram

I2C Demo for Master Write Function

The description of I2C demo code 2 is shown in the following table.

I2C Demo Code 2 Description

Demo 2

i2c_mw_demo.c

Sample Purpose

Demonstrate I2C master write function.

Brief Introduction

This sample code demonstrates the I2C master write function. The chip transmits some data to the I2C slave.

File Path

sdk\src\sample\io_demo\i2c\master_write\i2c_mw_demo.c

Function Entry

i2c_mw_demo()

Hardware Connection

As shown in I2C Demo Code 1/2/3 Hardware Connection Diagram. On EVB, connect P0_0 to the SCL of the I2C slave, connect P0_1 to the SDA of the I2C slave.

I2C SCL Pin Definition

#define PIN_I2C1_SCL P0_0

I2C SDA Pin Definition

#define PIN_I2C1_SDA P0_1

I2C ID

I2C1

Clock Speed

400000

Device Mode

Master

Address Mode

7-Bit

Slave Address

#define ADDR 0x08

ACK

ACK Enable

Expected Result

  1. Press the Reset button on the EVB, the I2C slave will receive data 0xaa, 0xbb, 0x66, 0x68, 0x77, 0x88.

  2. If the I2C transfer fails, the string i2c_mw_demo: Send failed will be displayed in the Debug Analyzer.

I2C Demo for Polling Mode

The description of I2C demo code 3 is shown in the following table.

I2C Demo Code 3 Description

Demo 3

i2c_polling_demo.c

Sample Purpose

Demonstrate how I2C writes and reads data in polling mode.

Brief Introduction

This sample code demonstrates the communication between the chip and the I2C slave. The chip writes some data to the I2C slave and then the chip reads data from the I2C slave.

File Path

sdk\src\sample\io_demo\i2c\polling\i2c_polling_demo.c

Function Entry

i2c_polling_demo()

Hardware Connection

As shown in I2C Demo Code 1/2/3 Hardware Connection Diagram. On EVB, connect P0_0 to the SCL of the I2C slave, connect P0_1 to the SDA of the I2C slave.

I2C SCL Pin Definition

#define PIN_I2C1_SCL P0_0

I2C SDA Pin Definition

#define PIN_I2C1_SDA P0_1

I2C ID

I2C1

Clock Speed

400000

Device Mode

Master

Address Mode

7-Bit

Slave Address

#define ADDR 0x08

ACK

ACK Enable

Expected Result

  1. Press the Reset button on the EVB, the I2C slave will receive data 0xaa and 0xbb, and the chip will receive four bytes from the I2C slave.

  2. If the I2C transfer fails, the string i2c_polling_demo: Send failed will be displayed in the Debug Analyzer.

I2C Demo for Slave Mode

The description of I2C demo code 4 is shown in the following table.

I2C Demo Code 4 Description

Demo 4

i2c_slave_demo.c

Sample Purpose

Demonstrate how I2C slave works.

Brief Introduction

This sample code demonstrates the communication between the chip and I2C master. The chip can read data from the I2C master and write data to the I2C master.

File Path

sdk\src\sample\io_demo\i2c\slave\i2c_slave_demo.c

Function Entry

i2c_slave_demo()

Hardware Connection

As shown in I2C Demo Code 4 Hardware Connection Diagram. On EVB, connect P0_0 to the SCL of the I2C master. On EVB, connect P0_1 to the SDA of the I2C master.

I2C SCL Pin Definition

#define PIN_I2C1_SCL P0_0

I2C SDA Pin Definition

#define PIN_I2C1_SDA P0_1

I2C ID

I2C1

Clock Speed

100000

Device Mode

Slave

Address Mode

7-Bit

Slave Address

0x50

ACK

ACK Enable

Expected Result

  1. Press the Reset button on the EVB.

  2. If the I2C master sends a read request, the master will receive data 0x66.

  3. If the I2C master sends a write command, the received data will be displayed in the Debug Analyzer.

The hardware connection of I2C demo code 4 is shown in the figure below.

../../../_images/I2C_Demo_4_Hardware_Connection_Diagram.png

I2C Demo Code 4 Hardware Connection Diagram

Functional Overview

The I2C bus is a two-wire serial interface, consisting of a serial data line (SDA) and a serial clock (SCL). These wires carry information between the devices connected to the bus. Each device is recognized by a unique address and can operate as either a transmitter or receiver, depending on the function of the device. Devices can also be considered masters or slaves when performing data transfers. A master is a device that initiates a data transfer on the bus and generates the clock signals to permit that transfer. At that time, any device addressed is considered a slave.

Feature List

  • Up to 3 I2C.

  • Two-wire I2C serial interface: consists of a serial data line (SDA) and a serial clock (SCL).

  • Support master and slave mode.

  • Support 7/10-bit addressing mode.

  • Support standard mode (0 to 100Kb/s).

  • Support fast mode (less than or equal to 400Kb/s) or fast mode plus (less than or equal to 1000Kb/s).

  • Interrupt or polling mode operation.

  • Support GDMA.

Transfer Protocol

Each byte sent on the SDA line must be 8 bits. There is no limit to the number of bytes that can be sent per transfer, and each byte must be followed by a response bit. The most significant bit (MSB) of the data is transmitted first. If the slave needs to complete some other functions, such as an internal interrupt service routine, it can receive or send the next complete data byte. The clock line SCL can be kept low to force the master to enter the wait state. When the slave is ready to receive the next data byte and release the clock line SCL, the data transfer continues.

../../../_images/Schematic_Diagram_of_I2C_Transmission_Protocol.jpg

Schematic Diagram of I2C Transmission Protocol

Master Mode

7-Bit Addressing Mode

Master Write

Master-transmitter transmits to slave-receiver with a 7-bit slave address. The transfer direction is not changed. All data is transmitted in byte format, with no limit on the number of bytes transferred per data transfer. After the master sends the address and read/write bit or the master transmits a byte of data to the slave, the slave-receiver must respond with the acknowledge signal. When a slave-receiver does not respond with an ACK pulse, the master aborts the transfer by issuing a stop condition. The slave must leave the SDA line high so that the master can abort the transfer.

../../../_images/Master_Write_in_7-bit_Addressing_Mode.jpg

Master Write in 7-Bit Addressing Mode

Master Read

In the first response, master-transmitter becomes master-receiver, and slave-receiver becomes slave-transmitter, and the first response is still generated by the slave. If the master is receiving data, the master responds to the slave-transmitter with an acknowledge pulse after a byte of data has been received, except for the last byte. This (NACK) is the way the master-receiver notifies the slave-transmitter that this is the last byte. The slave-transmitter relinquishes the SDA line after detecting the no acknowledge (NACK) so that the master can issue a stop condition.

../../../_images/Master_Read_in_7-bit_Addressing_Mode.jpg

Master Read in 7-Bit Addressing Mode

Master Repeat Read

When performing a write-before-read operation, both the start condition and the slave address are sent repeatedly, but the read/write bit is reversed.

../../../_images/Master_Repeat_Read_in_7-bit_Addressing_Mode.jpg

Master Repeat Read in 7-Bit Addressing Mode

10-Bit Addressing Mode

Master Write

Master-transmitter transmits to slave-receiver with a 10-bit slave address. The transfer direction is not changed.

../../../_images/Master_Write_in_10-bit_Addressing_Mode.jpg

Master Write in 10-Bit Addressing Mode

Master Read

Master-transmitter transmits to slave-receiver with a 10-bit slave address. The transfer direction is changed after the second read/write bit, master-transmitter becomes master-receiver, and slave-receiver becomes slave-transmitter.

../../../_images/Master_Read_in_10-bit_Addressing_Mode.jpg

Master Read in 10-Bit Addressing Mode

Master Repeat Read

The master sends data to the slave and then reads data from the same slave. The transfer direction is changed after the second read/write bit.

../../../_images/Master_Repeat_Read_in_10-bit_Addressing_Mode.jpg

Master Repeat Read in 10-Bit Addressing Mode

Clock Speed Setting Instructions

The I2C clock speed is related to the SCL rising time, which is affected by the pull-up resistor and capacitor. Users can configure the variable I2C_RisingTimeNs to calibrate the I2C clock speed. The default value of I2C_RisingTimeNs for RTL87x3D is 100, and the default value of I2C_RisingTimeNs for RTL87x3E and RTL87x3EP is 50. The following example demonstrates the calibration method of the I2C clock speed, taking the I2C source clock as 40MHz, the I2C clock speed as 400KHz, and the I2C_RisingTimeNs as 100.

  1. Set the variable I2C_RisingTimeNs to 100.

  2. Measure the I2C clock speed. For example, if the actual frequency measured is 411KHz, the period is: 1/411KHz = 2433 ns.

  3. Calculate the actual value of I2C_RisingTimeNs.

    1. SCL Low Time = SCL Low Period - SCL Falling Time + SCL Rising Time

    2. SCL High Time = SCL High Period + SCL Falling Time

    3. SCL Frequency = 1 / (SCL High Time + SCL Low Time)

    4. According to the formulas a to c, SCL Period = SCL Low Period + SCL High Period + SCL Rising Time

    5. SCL Low Period (ns) + SCL High Period (ns) = SCL Period (ns) - I2C_RisingTimeNs configured in the APP = 2500 - 100 = 2400

    6. Actual I2C_RisingTimeNs = Actual period - (SCL Low Period + SCL High Period) = 2433 - 2400 = 33

    7. Because the clock source of I2C is set to 40MHz, the precision of the I2C clock is 25ns. So the setting I2C_RisingTimeNs needs to be aligned to 25ns.

Program Examples

Master Mode Initialization Flow

I2C master mode initialization flow is shown in the following figure.

../../../_images/I2C_Master_Write_Operation_Flow_Chart.png

I2C Master Write Operation Flow Chart

The codes below demonstrate the I2C master mode initialization flow.

void driver_i2c_init(void)
{
   RCC_PeriphClockCmd(APBPeriph_I2C1, APBPeriph_I2C1_CLOCK, ENABLE);

   I2C_InitTypeDef  I2C_InitStructure;
   I2C_StructInit(&I2C_InitStructure);

   I2C_InitStructure.I2C_ClockSpeed = 400000;
   I2C_InitStructure.I2C_DeviveMode = I2C_DeviveMode_Master;
   I2C_InitStructure.I2C_AddressMode = I2C_AddressMode_7BIT;
   I2C_InitStructure.I2C_SlaveAddress = ADDR;
   I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

   I2C_Init(I2C1, &I2C_InitStructure);

   I2C_Cmd(I2C1, ENABLE);
}

Slave Mode Initialization Flow

I2C slave mode initialization flow is shown in the following figure.

../../../_images/I2C_Slave_Mode_Initialization_Flow_Chart.png

I2C Slave Mode Initialization Flow Chart

The codes below demonstrate the I2C slave mode initialization flow.

RCC_PeriphClockCmd(APBPeriph_I2C1, APBPeriph_I2C1_CLOCK, ENABLE);

I2C_InitTypeDef  I2C_InitStructure;
I2C_StructInit(&I2C_InitStructure);

I2C_InitStructure.I2C_ClockSpeed = 100000;
I2C_InitStructure.I2C_DeviveMode = I2C_DeviveMode_Slave;
I2C_InitStructure.I2C_AddressMode = I2C_AddressMode_7BIT;
I2C_InitStructure.I2C_SlaveAddress = 0x50;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

I2C_Init(I2C1, &I2C_InitStructure);

/* Config I2C interrupt */
I2C_INTConfig(I2C1, I2C_INT_RD_REQ | I2C_INT_RX_FULL | I2C_INT_STOP_DET, ENABLE);

NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = I2C1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);

I2C_Cmd(I2C1, ENABLE);

Master Write

The codes below demonstrate the operation flow of I2C sending data in master mode.

uint8_t I2C_WriteBuf[16] = {0xaa, 0xbb, 0x66, 0x68, 0x77, 0x88};

if (I2C_Success != I2C_MasterWrite(I2C1, I2C_WriteBuf, 6))
{
   IO_PRINT_ERROR0("i2c_mw_demo: Send failed");

   //Check Event
   if (I2C_CheckEvent(I2C1, ABRT_7B_ADDR_NOACK) == SET)
   {
      IO_PRINT_ERROR0("i2c_mw_demo: Wrong addr");
   }
   if (I2C_CheckEvent(I2C1, ABRT_GCALL_NOACK) == SET)
   {
      IO_PRINT_ERROR0("i2c_mw_demo: General call nack");
   }
   I2C_SendCmd(I2C1, I2C_WRITE_CMD, 0, I2C_STOP_ENABLE);
   I2C_Cmd(I2C1, DISABLE);
   I2C_Cmd(I2C1, ENABLE);
   I2C_MasterWrite(I2C1, I2C_WriteBuf, 6);
}

Master Repeat Read

The codes below demonstrate the operation flow of I2C send and receive data in master mode.

uint8_t I2C_WriteBuf[16] = {0xaa, 0xbb, 0x66, 0x68, 0x77, 0x88};
uint8_t I2C_ReadBuf[16] = {0, 0, 0, 0};

if (I2C_Success != I2C_RepeatRead(I2C1, I2C_WriteBuf, 2, I2C_ReadBuf, 4))
{
   IO_PRINT_ERROR0("i2c_polling_demo: Send failed");

   //Check Event
   if (I2C_CheckEvent(I2C1, ABRT_7B_ADDR_NOACK) == SET)
   {
      IO_PRINT_ERROR0("i2c_polling_demo: Wrong addr");
   }
   if (I2C_CheckEvent(I2C1, ABRT_GCALL_NOACK) == SET)
   {
      IO_PRINT_ERROR0("i2c_polling_demo: General call nack");
   }
}