MLX90640 BAB/BAA 驱动调试

在这里插入图片描述

mlx90640-i2c.c 为驱动,dts配置参考
&i2c4 {
    status = "okay";
    clock-frequency = <400000>;

        mlx90640@33 {
               compatible = "mlx90640";
               reg = <0x33>;
               status = "okay";
        };
};
#include <linux/module.h>
#include <linux/init.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#ifdef CONFIG_OF_GPIO
#include <linux/of_platform.h>
#endif
#include <linux/of_gpio.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/kthread.h> 
#include <linux/miscdevice.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/time.h>
#include <linux/device.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <asm/param.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>

#define DRIVER_NAME 	"mlx90640"
#define MLX90640_IOCTL_MAGIC			'm'
#define MLX90640_GET_DATA	_IOR(MLX90640_IOCTL_MAGIC, 1, int *)
#define MLX90640_SET_DATA	_IOR(MLX90640_IOCTL_MAGIC, 2, int *)


struct mlx90640_chip {
	struct mutex i2c_lock;
	struct i2c_client *client;
	const char *const *names;
};

struct MLX90640_R_DATA{
	uint16_t reg;
	uint16_t size;
	uint16_t buff[1664];
};

struct MLX90640_W_DATA{
	uint16_t reg;
	uint16_t size;
	uint16_t data;
};

struct mlx90640_chip *gchip = NULL;

static int mlx90640_open(struct inode *inode, struct file *filp)
{
	return 0;
}

int mlx90640_release(struct inode *inode, struct file *filp)
{
	return 0; 
}

static int i2c_master_recv_(struct i2c_client *client,char *msgbuf,uint16_t *data,uint16_t nMemAdddressRead)
{
	struct i2c_msg msgs[2];
	struct i2c_adapter *adap = client->adapter;
	int ret;
	uint16_t bytesRemaining = nMemAdddressRead * 2;
	int cnt = 0;
	int i = 0;
	uint16_t *p = data;
	char i2cData[1664];

	msgs[0].addr = client->addr;
	msgs[0].flags = I2C_M_TEN;	/* write */
	msgs[0].len = 2;
	msgs[0].buf = msgbuf;

	msgs[1].addr = client->addr;
	msgs[1].flags = I2C_M_RD | I2C_M_NOSTART;
	msgs[1].len = bytesRemaining;
	msgs[1].buf = i2cData;

	memset(i2cData,0,bytesRemaining);
	ret = i2c_transfer(adap,&msgs,2);
	for(cnt = 0;cnt < nMemAdddressRead;cnt++){
		i = cnt << 1;
		*p++ = ((uint16_t)i2cData[i] << 8) | i2cData[i+1];
	}
	return 0;
}

static int mlx90640_write_data(struct i2c_client *client,uint16_t reg,uint16_t buf)
{
	int ret = 0;
	u8 abuf[4];
	abuf[0] = reg >> 8;
	abuf[1] = reg;	
	abuf[2] = buf >> 8;
	abuf[3] = buf;	
	ret = i2c_master_send(client,abuf,4);
	return ret;
}

static int mlx90640_read_data(struct i2c_client *client,uint16_t reg,uint16_t *data,uint16_t nMemAdddressRead)
{
	int rc;
	u8 msgbuf[2];
	msgbuf[0] = reg >> 8;
	msgbuf[1] = reg;
	rc = i2c_master_recv_(client,msgbuf,data,nMemAdddressRead);
	return 0;
}

static long mlx90640_ioctl(struct file *file, unsigned int cmd,unsigned long arg)
{
	struct MLX90640_R_DATA data;
	struct MLX90640_W_DATA w_data;
	mutex_lock(&gchip->i2c_lock);
	switch(cmd){
		case MLX90640_GET_DATA:
			if(copy_from_user((void*)&data,(void __user*)arg,sizeof(struct MLX90640_R_DATA))){
				printk("MLX90640_ioctl SE_IOC_GET_DATA copy_from_user error\n");
				mutex_unlock(&gchip->i2c_lock);
				return -EFAULT;
			}	
			if(mlx90640_read_data(gchip->client,data.reg,&data.buff[0],data.size) != 0){
				printk("MLX90640_ioctl read data failed,reg:0x%x ,size:%d \n",data.reg,data.size);
				mutex_unlock(&gchip->i2c_lock);
				return -EFAULT;
			}
			if(copy_to_user((void __user*)arg,(void*)&data,sizeof(struct MLX90640_R_DATA))){
				printk("MLX90640_ioctl SE_IOC_GET_DATA copy_to_user error\n");
				mutex_unlock(&gchip->i2c_lock);
				return -EFAULT;
			}
			break;
		case MLX90640_SET_DATA:
			if(copy_from_user((void*)&w_data,(void __user*)arg,sizeof(struct MLX90640_W_DATA))){
				printk("MLX90640_ioctl SE_IOC_SET_DATA copy_from_user error\n");
				mutex_unlock(&gchip->i2c_lock);
				return -EFAULT;
			}
			mlx90640_write_data(gchip->client,w_data.reg,w_data.data);
			break;
		default:
			printk("MLX90640_ioctl cmd:0x%x error\n",cmd);
			break;	
	}
	mutex_unlock(&gchip->i2c_lock);
	return 0;
}

static struct file_operations mlx90640_fops = 
{
	.owner = THIS_MODULE,
	.open = mlx90640_open,
	.release = mlx90640_release,
	.unlocked_ioctl = mlx90640_ioctl,
};

static struct miscdevice mlx90640_dev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "mlx90640",
	.fops = &mlx90640_fops,
};

static int mlx90640_probe(struct i2c_client *client,const struct i2c_device_id *id)
{
	struct mlx90640_chip *chip;
	struct i2c_adapter *adapter = client->adapter;
	int ret;

    	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)){
        	return -ENODEV;
    	}
		
	chip = devm_kzalloc(&client->dev,sizeof(struct mlx90640_chip), GFP_KERNEL);
	if (chip == NULL)
		return -ENOMEM;

	chip->names = DRIVER_NAME;

	chip->client = client;

	mutex_init(&chip->i2c_lock);

	gchip = chip;

	struct MLX90640_R_DATA data;
	data.reg = 0x8000;
	data.size = 1;	
	mlx90640_read_data(gchip->client,data.reg,&data.buff[0],data.size);
#if 0
	struct MLX90640_W_DATA w_data;
	w_data.reg = 0x800D;
	w_data.size = 1;
	w_data.data = 0x1291;
	MLX90640_write_data(gchip->client,w_data.reg,w_data.data);
#endif
	data.reg = 0x800D;
	mlx90640_read_data(gchip->client,data.reg,&data.buff[1],data.size);
	printk("harris mlx90640_probe read 0x8000->0x%x 0x800D->0x%x\n",data.buff[0],data.buff[1]);

	ret = misc_register(&mlx90640_dev);

	return 0;
}

static int mlx90640_remove(struct i2c_client *client)
{
	return 0;
}

static const struct i2c_device_id mlx90640_dt_id[] = {
	{"mlx90640", 0},
	{ }
};
MODULE_DEVICE_TABLE(i2c, mlx90640_dt_id);

static const struct of_device_id mlx90640_dt_ids[] = {
	{ .compatible = "mlx90640", },
	{ }
};
MODULE_DEVICE_TABLE(i2c, mlx90640_dt_ids);

static struct i2c_driver mlx90640_driver = {
	.probe		= mlx90640_probe,
	.remove		= mlx90640_remove,
	.driver = {
		.name	= DRIVER_NAME,
		.owner = THIS_MODULE,	
		.of_match_table = of_match_ptr(mlx90640_dt_ids),
	},
	.id_table = mlx90640_dt_id,
};

static int __init mlx90640_init(void)
{
	return i2c_add_driver(&mlx90640_driver);
}

static void __exit mlx90640_exit(void)
{
	i2c_del_driver(&mlx90640_driver);
}

subsys_initcall(mlx90640_init);
module_exit(mlx90640_exit);

MODULE_AUTHOR("xxx");
MODULE_DESCRIPTION("i2c driver for mlx90640");
MODULE_LICENSE("GPL");

MLX90640 有两个型号, A 型和 B 型,型号全称为:MLX90640ESF_BAA/BAB。他们区别在于:视场角不同: A 型为 11075° , B 型为 5535° ,通俗一点讲就是 A 型是广角,所以镜头矮一些,视野更宽,但对远处物体的捕捉能力更低, B 型更适于拍摄稍远的物体。精度不同: A 型的噪声比 B 型大,所以 B 型的绝对温度和灵敏度都好一些。做红外热像仪,一般用B型。

mlx90640 驱动调试
QQ 交流入群:712288614

视频观看链接:学习视频连接

淘宝模块购买链接:淘宝购买链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

baidu_37552881

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值