ROCKCHIP 系列芯片为客户提供了标准 I2C 总线,方便客户实现对不同外接设备的控制和访问。I2C 总
线控制器通过串行数据(SDA)线和串行时钟 (SCL)线在连接到总线的器件间传递信息。每个器件都
有一个唯一的地址识别(无论是微控制器——MCU、LCD 驱动器、存储器或键盘接口),而且都可以
作为一个发送器或接收器(由器件的功能决定)。
Rockchip I2C 控制器支持下列功能︰
风火轮科技开发一款rk3588s的主板youyeetoo R1,该主板提供40pin扩展管脚,其中提供3路i2c管脚使用。管脚分布如下图所示:
这里提供完整的app
Android系统的权限管理是十分严格的,使用c++或者java操作Android根文件系统里的文件或资源需要对应的权限。这里编写的ndk程序是基于 system app的作为模板进行编写。system app请参考创建system app这一章。
#include <jni.h>
#include <string>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <android/log.h>
#define LOG_TAG "R1-I2cTest"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define I2C_DEVICE "/dev/i2c-5"
#define SLAVE_DEVICE_ADDR 0x5d
#define REG_ADDR 0x8047
/*函数名:slave_device_write
**功能:向slave device写数据
**参数:fd:slave device对应I2C控制器设备节点的文件名
** dev_addr:slave device的I2C从设备地址
** reg_addr:slave device的寄存器地址
** data_buf:要向slave device写数据的数据buf
** data_len:要写多少个字节。
**返回值:负数表示操作失败,其他为成功
*/
int slave_device_write(int fd, unsigned char dev_addr, unsigned short reg_addr, unsigned char * data_buf,int data_len)
{
int ret;
int i;
unsigned char *msg_buf;
unsigned char reg_len = 0;
struct i2c_rdwr_ioctl_data data;
struct i2c_msg messages;
reg_len = (reg_addr >> 8) ? 1 : 0;
msg_buf = (unsigned char *)malloc(reg_len + 1 + data_len);
if (msg_buf == NULL) {
LOGE("malloc fail\n");
return -1;
}
msg_buf[0] = (reg_addr >> 8) & 0xff;
msg_buf[0 + reg_len] = reg_addr & 0xff;
reg_len++;
messages.addr = dev_addr;
messages.flags = 0;
messages.len = data_len + reg_len;
for(i = reg_len; i < messages.len; i++) {
msg_buf[i] = data_buf[i - reg_len];
}
messages.buf = msg_buf;
data.msgs = &messages;
data.nmsgs = 1;
if(ioctl(fd, I2C_RDWR, &data) < 0)
{
LOGE("I2C_RDWR err \n");
return -1;
}
sleep(1);
free(msg_buf);
return 0;
}
/*函数名:slave_device_read
**功能:从slave_device读数据
**参数:fd:slave_device对应I2C控制器设备节点的文件名
** dev_addr:slave_device的I2C从设备地址
** reg_addr:slave_device的寄存器地址
** data_buf:存放从slave_device读数据的buf
** len:要读多少个字节。
**返回值:负数表示操作失败,其他为成功
*/
int slave_device_read(int fd, unsigned char dev_addr, unsigned short reg_addr, unsigned char * data_buf,int data_len)
{
int ret;
unsigned char *w_buf;
struct i2c_rdwr_ioctl_data data;
struct i2c_msg messages[2];
unsigned char reg_len = 0;
reg_len = (reg_addr >> 8) ? 1 : 0;
w_buf = (unsigned char *)malloc( reg_len + 1);
if (w_buf == NULL) {
LOGE("malloc fail\n");
return -1;
}
w_buf[0] = (reg_addr >> 8) & 0xff;
w_buf[0 + reg_len] = reg_addr & 0xff;
reg_len++;
messages[0].addr = dev_addr;
messages[0].flags = 0;
messages[0].len = reg_len;
messages[0].buf = w_buf;
messages[1].addr = dev_addr;
messages[1].flags = I2C_M_RD;
messages[1].len = data_len;
messages[1].buf = data_buf;
data.msgs = messages;
data.nmsgs = 2;
if(ioctl(fd, I2C_RDWR, &data) < 0)
{
LOGE("I2C_RDWR err \n");
return -1;
}
sleep(1);
free(w_buf);
return 0;
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_youyeetoo_r1_1i2cdemo_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
int fd,i,ret=0;
unsigned char rd_buf[8] = {0};
unsigned char wr_buf[8] = {0};
char show_buf[32] = {0};
LOGI("hello,this is I2C_RDWR i2c test \n");
fd =open(I2C_DEVICE, O_RDWR);
if (fd< 0){
LOGE("open /dev/i2c-5 failed \n");
return env->NewStringUTF("open /dev/i2c-5 failed \n");
}
for(i=0;i<8;i++)
wr_buf[i]=i;
// slave_device_write(fd,SLAVE_DEVICE_ADDR,REG_ADDR,wr_buf,8);
slave_device_read(fd,SLAVE_DEVICE_ADDR,REG_ADDR,rd_buf,8);
for(i=0;i<8;i++){
sprintf(show_buf + i*3, "%02x ",rd_buf[i]);
}
close(fd);
return env->NewStringUTF(show_buf);
}