在hi3516平台上使用i2C控制tmp117

1.前言

这阵子在搞hi3516DV300的i2c通信,加上温度传感器tmp117为从机进行通信。梳理了一下关于hi3516DV300的调用i2c的方法,分别是APP,命令行和驱动三方面。

2.查看设备树是使能i2c-2

rp-hi3516dv300-sdk020/osdrv/opensource/kernel/linux-4.9.y-smp/arch/arm/boot/dts下的hi3516dv300-demb.dts中status 改为 “okay”

&i2c_bus2 {
   
    status = "okay";
    clock-frequency = <100000>;
};

3.需要配置SDA和SCL引脚的复用状态

i2c
引脚描述
我们这边使用的i2c-2来与tmp117通信。
需要将 0x111f0018和0x111f001c两个寄存器配置成0x201,有两种方法:

a.使用himm工具配置SDA和SCL引脚的复用状态

#在linux命令行中配置
himm 0x111F001C 0x201  (这是SCL的配置)
himm 0x111F0018	0x201  (这是SDA的配置)

b.在u-boot中配置SDA和SCL引脚的复用状态

进入展开后SDK的 rp-hi3516dv300-sdk020/osdrv/tools/pc/uboot_tools 目录下的文件:
Hi3516DV300-DMEB_4L_FLYBY-DDR3_1800M_512MB_16bitx2-A7_900M-SYSBUS_300M.xlsm
的pinout页面进行添加,好处是不用重新上电就要用himm去修改。
添加配置SDA和SCL引脚的复用状态

#将修改后的文件编译进u-boot
cd ./osdrv/tools/pc/uboot_tools
tar -zxf hiregbin-v5.0.1.tgz
cd hiregbin-v5.0.1
sudo chmod +x hiregbin
./hiregbin ../Hi3516DV300-DMEB_4L_FLYBY-DDR3_1800M_512MB_16bitx2-A7_900M-SYSBUS_300M.xlsm ./reg.bin
cp reg.bin ../../../../opensource/uboot/u-boot-2016.11/.reg
cd ../../../../opensource/uboot/u-boot-2016.11
make ARCH=arm CROSS_COMPILE=arm-himix200-linux- u-boot-z.bin

修改后可以用himm去读取看看。

4.通过命令行去读写i2c

a.在控制台使用i2c_read命令对I2C外围设备进行读操作:
i2c_read <i2c_num> <device_addr> <reg_addr> <end_reg_addr> <reg_width> <data_width> <reg_step>

例如:读挂载在I2C控制器2上、设备地址为0x49设备的0x0寄存器:

#0X92 = 0x49<<1
i2c_read 2 0x92 0x0 0x0 0x1 0x2

i2c_num:I2C控制器序号(对应《Hi3516CV500 专业型 Smart IP Camera SoC用户指南》中的I2C控制器编号)
device_addr:外围设备地址(Hi3516CV500支持标准地址(7bit)和扩展地址(10bit))
reg_addr:读外围设备寄存器操作的开始地址
end_reg_addr:读外围设备寄存器操作的结束地址
reg_width:外围设备的寄存器位宽(Hi3516CV500支持8/16/24/32bit)
data_width:外围设备的数据位宽(Hi3516CV500支持8/16/24/32bit)
reg_step:连续读外围设备寄存器操作时递增幅值,默认为1,即连续读寄存器,读取单个寄存器时不使用该参数

b.在控制台使用i2c_write命令对I2C外围设备进行写操作:
i2c_write <i2c_num> <device_addr> <reg_addr> <value> <reg_width> <data_width>

i2c_num:I2C控制器编号(对应《Hi3516CV500 专业型 Smart IP Camera SoC用户指南》中的I2C控制器编号)
device_addr:外围设备地址(Hi3516CV500支持标准地址(7bit)和扩展地址(10bit))
reg_addr:写外围设备寄存器操作的地址
value:写外围设备寄存器操作的数据
reg_width:外围设备的寄存器位宽(Hi3516CV500支持8/16/24/32bit)
data_width:外围设备的数据位宽(Hi3516CV500支持8/16/24/32bit)

5.用ioctl控制读写i2c设备。

通过打开/dev/i2c-2来打开设备,ioctl来对i2c设备读写控制。

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <errno.h>

#define I2C2_ADDR     "/dev/i2c-2"
#define TMP117_ADDR    0x49

#define I2C_SLAVE       0x0703	/* Use this slave address */
#define I2C_SLAVE_FORCE	0x0706	/* Use this slave address, even if it*/
#define I2C_RDWR        0x0707	/* Combined R/W transfer (one STOP only) */

int i2c_dev_Open( int *fd,unsigned char dev_addr)
{
   
    int retval = 0;
	int tmpfd =0;
    tmpfd = open(I2C2_ADDR, O_RDWR);
    if (tmpfd < 0) {
   
        printf("i2c_dev_Open  %s addr:%x error!\n",I2C2_ADDR,dev_addr);
		retval = -1;
        goto end0;
    }

    retval = ioctl(tmpfd, I2C_SLAVE, dev_addr);
    if (retval < 0) {
   
        retval = ioctl(tmpfd, I2C_SLAVE_FORCE, dev_addr);
        if(retval < 0)
        {
   
            printf("i2c_dev_Open CMD_SET_I2C_SLAVE error! %s\n",strerror(errno));
            close(tmpfd);
			goto end0;
        }
    }

    printf("i2c_dev_Open %s suc! [%d]\n",I2C2_ADDR, tmpfd);
	*fd = tmpfd;
end0:
    return retval;
}

int i2c_dev_Close(int *fd)
{
   
	int tmpfd =*fd;
    if(tmpfd)
        close(tmpfd);
    *fd = -1;
    return 0;
}


int8_t i2c_dev_ReadByte(int fd,unsigned char dev_addr,unsigned char reg_addr,unsigned char *data,int len)
{
   
    int retval = 0;

	unsigned char tmp_reg_addr = 0x00;
    struct i2c_rdwr_ioctl_data rdwr;
    struct i2c_msg msg[2];
	unsigned short Temperature ;

    memset(data,  0x0, len);


    msg[0].addr = dev_addr;
    msg[0].flags = 0;
    msg[0].len = 1;
    msg[0].buf = &tmp_reg_addr;

    msg[1].addr = dev_addr;
    msg[1].flags = I2C_M_RD;
    msg[1].len = 2;
    msg[1].buf = data;

    rdwr.msgs = &msg[0];
    rdwr.nmsgs = 2;
    retval = ioctl(fd, I2C_RDWR, &rdwr);
    if (retval != 2) {
   
        printf("TMP117_ReadByte CMD_I2C_READ error!\n");
        retval = -1;
        goto end0;
    }
	Temperature = data[0]<<8|data[1];
	printf("TMP117_ReadByte %s addr:%x reg:%x data:%x(%d)!\n",I2C2_ADDR,dev_addr,reg_addr,Temperature,Temperature);
end0:
    return retval;
}




int main(int argc, char* argv[])
{
   
	int rc;
	int fd =0;
	unsigned short Temperature ;
	unsigned char data[2] ;
	printf("TMP117_Open \n"
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值