The ROCKCHIP series of chips provides customers with a standard I2C bus to facilitate customers to control and access different external devices. I2C total
The line controller passes information between devices connected to the bus via the serial data (SDA) line and the serial clock (SCL) line. Each device
has a unique address identification (whether it is a microcontroller - MCU, LCD driver, memory or keyboard interface) and can
Acts as a transmitter or receiver (depending on device functionality).
Rockchip I2C controller supports the following features:
Hot Wheels Technology has developed a rk3588s motherboard youyeetoo R1, which provides 40pin expansion pins, including 3-way i2c pins. The pin distribution is shown in the figure below:
The permission management of the Android system is very strict. Using c++ or java to operate files or resources in the Android root file system requires corresponding permissions. The ndk program written here is written based on the system app as a template. For system app, please refer to the chapter Creating system app.
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
/* The device node of the I2C controller corresponding to the slave device */
#define I2C_DEVICE "/dev/i2c-5"
/* I2C device address of slave_device */
#define SLAVE_DEVICE_ADDR 0x32
/*Function name: slave_device_write
**Function: Write data to slave device
**Parameter: fd: slave device corresponds to the file name of the I2C controller device node
** dev_addr: I2C slave device address of slave device
** reg_addr: register address of slave device
** data_buf: data buf to write data to slave device
** len: How many bytes to write. In this example, the current maximum supported size is 8 bytes
**Return value: A negative number indicates that the operation failed, others indicate success.
*/
int slave_device_write(int fd, unsigned char dev_addr, unsigned char reg_addr, unsigned char * data_buf,int len)
{
int ret;
unsigned char msg_buf[9];
struct i2c_rdwr_ioctl_data data;
struct i2c_msg messages;
/* 1. Build msg_buf*/
/* 1.1. Assign the first address of the register to be operated to the first byte of data to be used for I2C data communication */
msg_buf[0] = reg_addr;
/* 1.2. Assign the data buf to be written to slave_device after the slave device register in I2C data communication */
if (len < 9) { /* This demo supports writing up to 8 bytes of data in one page to the slave device at one time */
memcpy((void *) &msg_buf[1], data_buf, len); //After the first bit is data
} else {
printf("This function supports up to 8 bytes at a time !!!\n");
return -1;
}
/* 2. Build struct i2c_msg messages */
/* 2.1. Assign the I2C slave device address of the slave device */
messages.addr = dev_addr;
/* 2.2. Assign flags to complete the writing function for this I2C communication */
messages.flags = 0;
/* 2.3. Assign len to the length of the data buf + the data length of the slave device register address */
messages.len = len+1;
/* 2.4. Construct the data buf of the message package*/
messages.buf = msg_buf;
/* 3. Build struct i2c_rdwr_ioctl_data data */
/* 3.1. Assign the prepared message package to the msgs message in i2c_rdwr_ioctl_data*/
data.msgs = &messages;
/* 3.2. Since this I2C communication only has write actions, the number of messages is 1 */
data.nmsgs = 1;
/* 4. Call the driver layer’s read-write combined I2C data transmission */
if(ioctl(fd, I2C_RDWR, &data) < 0)
{
printf("I2C_RDWR err \n");
return -1;
}
/* 5. Wait for I2C bus writing to complete */
sleep(1);
return 0;
}
/*Function name: slave_device_read
**Function: Read data from slave_device
**Parameter: fd: slave_device corresponds to the file name of the I2C controller device node
** dev_addr: I2C slave device address of slave_device
**reg_addr: register address of slave_device
** data_buf: stores the buf that reads data from slave_device
** len: How many bytes to read.
**Return value: A negative number indicates that the operation failed, others indicate success.
*/
int slave_device_read(int fd, unsigned char dev_addr, unsigned char reg_addr, unsigned char * data_buf,int len)
{
int ret;
unsigned char msg_buf[9];
struct i2c_rdwr_ioctl_data data;
struct i2c_msg messages[2];
/* 1. Build struct i2c_msg messages */
/* 1.1. Construct the first message messages[0] */
/* 1.1.1. Assign the I2C slave device address of slave_device */
messages[0].addr = dev_addr;
/* 1.1.2. Assign flags to complete the writing action for this I2C communication */
messages[0].flags = 0;
/* 1.1.3. 赋值len为slave_device寄存器地址的数据长度是1 */
messages[0].len = 1;
/* 1.1.4. The data for this write action is to read the first address of the slave_device register*/
messages[0].buf = ®_addr;
/* 1.2. Construct the second message messages[1] */
/* 1.2.1. Assign the I2C slave device address of slave_device */
messages[1].addr = dev_addr;
/* 1.1.2. Assign flags to complete the read action for this I2C communication */
messages[1].flags = I2C_M_RD;
/* 1.1.3. Assign len to the data length len of the slave_device register to be read */
messages[1].len = len;
/* 1.1.4. The buf location where the data of this read action is to be stored */
messages[1].buf = data_buf;
/* 2. Build struct i2c_rdwr_ioctl_data data */
/* 2.1. Assign the prepared message package to the msgs message in i2c_rdwr_ioctl_data*/
data.msgs = messages;
/* 2.2. Since this I2C communication includes both writing and reading actions, the number of messages is 2 */
data.nmsgs = 2;
/* 3. Call the driver layer’s read-write combined I2C data transmission */
if(ioctl(fd, I2C_RDWR, &data) < 0)
{
printf("I2C_RDWR err \n");
return -1;
}
/* 4. Wait for I2C bus reading to complete */
sleep(1);
return 0;
}
int main()
{
int fd,i,ret=0;
unsigned char w_add=0x10;
/* Data buf to be read*/
unsigned char rd_buf[8] = {0};
/* Data buf to be written*/
unsigned char wr_buf[8] = {0};
printf("hello,this is I2C_RDWR i2c test \n");
/* Open the I2C controller file corresponding to slave_device */
fd =open(I2C_DEVICE, O_RDWR);
if (fd< 0)
{
printf("open"I2C_DEVICE"failed \n");
}
/* Write the data to be written into the following buf */
for(i=0;i<8;i++)
wr_buf[i]=i;
/* Complete the function of reading data from slave_device through I2C_RDWR */
slave_device_write(fd,SLAVE_DEVICE_ADDR,w_add,wr_buf,8);
/* Complete the function of writing data to slave_device through I2C_RDWR */
slave_device_read(fd,SLAVE_DEVICE_ADDR,w_add,rd_buf,8);
for(i=0;i<8;i++)
{
printf("rd_buf is :%d\n",rd_buf[i]);
}
/* After completing the operation, close the device file of the I2C controller corresponding to slave_device */
close(fd);
return 0;
}