0
点赞
收藏
分享

微信扫一扫

驱动

龙毓七七 08-08 21:00 阅读 51


#include "driverapp.h"



#define I2C_DEVICE_ADDR		0x1d
#define I2C_WRITE_MODE	 	0
#define I2C_READ_MODE 	 	1



#define CHIP_ID_REG			0x0d
#define CRTL_REG			0x2a
#define XYZ_DATA_REG		0x0e
#define OUT_XYZ_DATA_REG	0x01


#define clk_out()		nxp_soc_gpio_set_io_dir(PAD_GPIO_D+6,1)
#define data_out() 		nxp_soc_gpio_set_io_dir(PAD_GPIO_D+7,1)	//将gpioD7模式给输出
#define data_in() 		nxp_soc_gpio_set_io_dir(PAD_GPIO_D+7,0)	//将gpioD7模式给输入


#define clk_set()		nxp_soc_gpio_set_out_value(PAD_GPIO_D+6,1)  //将gpioD6设置高电平
#define clk_clear()		nxp_soc_gpio_set_out_value(PAD_GPIO_D+6,0)	//将gpioD6设置低电平
#define data_set()		nxp_soc_gpio_set_out_value(PAD_GPIO_D+7,1)	//将gpioD7设置高电平
#define data_clear() 	nxp_soc_gpio_set_out_value(PAD_GPIO_D+7,0)	//将gpioD7设置低电平
#define data_get()		nxp_soc_gpio_get_in_value(PAD_GPIO_D+7)

#define demo_i2c_delay()			udelay(50)
//封装发送起始信号函数
static void demo_i2c_start(void){
	//时钟gpio输出
	data_out();
	//时钟为高
	clk_set();
	//数据为高
	data_set();
	//延时
	demo_i2c_delay();
	//数据为低
	data_clear();
	demo_i2c_delay();
	//时钟为低
	clk_clear();
}
//封装发送终止信号函数
static void demo_i2c_stop(void){
	//时钟gpio输出
	data_out();
	//时钟为高
	clk_set();
	//数据为低
	data_clear();
	//延时
	demo_i2c_delay();
	//数据为高
	data_set();
	demo_i2c_delay();
	//时钟为低
	clk_clear();
	
}
//封装发送ack函数
static void demo_i2c_send_ack(unsigned char ack){
	data_out();
	clk_clear();
	if(ack)
		data_set();
	else
		data_clear();

	demo_i2c_delay();
	clk_set();
	demo_i2c_delay();
	clk_clear();
	
}
//封装接受ack函数
static unsigned char  demo_i2c_receive_ack(void){
	unsigned char ack = 0;
	data_in();
	clk_clear();
	demo_i2c_delay();
	clk_set();
	demo_i2c_delay();
	ack = data_get();
	clk_clear();
	return ack;

}
//封装发送8位数据函数
static void demo_i2c_send(unsigned char data){
	signed char i;	
	data_out();
	clk_clear();
	for(i=7;i>=0;i--){
		
		if(data&(1<<i))
			data_set();
		else
			data_clear();

		demo_i2c_delay();
		clk_set();
		demo_i2c_delay();
		clk_clear();
		
	}

	

}
static unsigned char demo_i2c_receive(void){

	unsigned char data = 0;
	signed char i;
	data_in();
	clk_clear();
	for(i=7;i>=0;i--){
		
		demo_i2c_delay();
		clk_set();
		demo_i2c_delay();
		data |= (data_get()<<i);
		clk_clear();
	}
	return data;


}

//模拟一次通信过程
static void demo_i2c_write_bytes(unsigned char *buf,unsigned char reg,int len)
{
	int i=0;
	
	demo_i2c_start();
	demo_i2c_send((I2C_DEVICE_ADDR<<1)|I2C_WRITE_MODE);
	if(demo_i2c_receive_ack())
		demo_dbg("i2c write addr error!\n");
	demo_i2c_send(reg);/* deivce address */
	if(demo_i2c_receive_ack())
		demo_dbg("i2c write reg error!\n");

	while(len--)
	{		
		demo_i2c_send(buf[i++]);/* send data */
		if(demo_i2c_receive_ack())
			demo_dbg("i2c write data error!\n");
	}
	demo_i2c_stop();	
}
static void demo_i2c_read_bytes(unsigned char *buf,unsigned char reg,int len)
{
	int i=0;
	
	demo_i2c_start();
	demo_i2c_send((I2C_DEVICE_ADDR<<1)|I2C_WRITE_MODE);
	if(demo_i2c_receive_ack())
		demo_dbg("i2c write addr error!\n");
	demo_i2c_send(reg);/* deivce address */
	if(demo_i2c_receive_ack())
		demo_dbg("i2c write reg error!\n");
//	demo_i2c_stop();	
	
	demo_i2c_start();
	demo_i2c_send((I2C_DEVICE_ADDR<<1)|I2C_READ_MODE);
	if(demo_i2c_receive_ack())
		demo_dbg("i2c write addr error!\n");
#if 1
	while(len--)
	{
		buf[i++] = demo_i2c_receive();
		if(len >0)
			demo_i2c_send_ack(0);
	}
	demo_i2c_send_ack(1);
#else	
	for(i=0;i<len;i++)
	{
		buf[i] = demo_i2c_receive();
		demo_i2c_send_ack((len==1)?1:(i/(len-1)));/* 条件表达式保证最后一次发1其它为0 */
	}
	
#endif	
	demo_i2c_stop();	
}


static void demo_i2c_device_init(void)
{
	unsigned char data = 0;
	nxp_soc_gpio_set_io_func(PAD_GPIO_D+6,0);//初始化clk功能
	nxp_soc_gpio_set_io_func(PAD_GPIO_D+7,0);//初始化sda功能
	data_out();//将sda设置为输出
	clk_out();//将clk设置为输出
	demo_i2c_read_bytes(&data,CHIP_ID_REG,1);//读mmaID_REG寄存器值
	demo_dbg("mma8653 chip id = 0x%x\n",data);
	/* do enable 1 */
	data |= 1;
	demo_i2c_write_bytes(&data,CRTL_REG,1);//使能CRTL_REG为avtive
}

static int demo_i2c_open(struct inode *pinode, struct file *pfile)
{
	demo_i2c_device_init();
	return 0;
}
 static int demo_i2c_close(struct inode *pinode, struct file *pfile)
{
	
	unsigned char data = 0;
	
	/* do desable 0 */
	data &= ~1;
	demo_i2c_write_bytes(&data,CRTL_REG,1);//关闭
	return 0;
}
static ssize_t demo_i2c_read(struct file *pfile, char __user *pbuf, size_t count, loff_t *poffset)
{

	unsigned char data[10] = {0};
	short x,y,z;
	demo_i2c_read_bytes(data,OUT_XYZ_DATA_REG,7);
	x = (data[0]<<2)|(data[1]>>6);
	y = (data[2]<<2)|(data[3]>>6);
	z = (data[4]<<2)|(data[5]>>6);
	x = (short)(x<<6)>>6;
	y = (short)(y<<6)>>6;
	z = (short)(z<<6)>>6;
	demo_dbg("x=%03d,y=%03d,z=%03d\n",x,y,z);
	mdelay(300);
	return 1;
	
}
static struct file_operations demo_i2c_fops = {
	.owner = THIS_MODULE,
	.open = demo_i2c_open,
	.release = demo_i2c_close,
	.read = demo_i2c_read,
};

static struct miscdevice demo_i2c_misc = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "demo_mma",
	.fops = &demo_i2c_fops,
};

static int  __init demo_i2c_init(void)
{
	//注册杂项驱动
	return misc_register(&demo_i2c_misc);
	
}

static void  __exit demo_i2c_exit(void)
{
	//注销杂项
	  misc_deregister(&demo_i2c_misc);
}

module_init(demo_i2c_init);
module_exit(demo_i2c_exit);

MODULE_LICENSE("Dual BSD/GPL");	//BSD/GPL双重许可证
MODULE_AUTHOR("edu");		//模块作者(可选)




举报

相关推荐

0 条评论