linux gpio模拟i2c
来源:互联网 发布:90后程序员demongao 编辑:程序博客网 时间:2024/06/10 13:39
linux gpio模拟i2c 收藏/*这是我模仿其他人写的程序,仅仅是把他改写成适合自己开发板的程序*/#include <linux/miscdevice.h>#include <mach/regs-gpio.h>#include <mach/hardware.h>#include <linux/fs.h>#define DEVICE_NAME "FINALL"#define RETRY_TIMES 1#define GPIO_SCL S3C2410_GPF3#define GPIO_SDA S3C2410_GPF0#define GPIO_SDA_OUTP S3C2410_GPF0_OUTP#define GPIO_SDA_INP S3C2410_GPF0_INP#define GPIO_SCL_OUTP S3C2410_GPF3_OUTPvoid I2C_SCL_OUTP( void ){ s3c2410_gpio_cfgpin(GPIO_SCL,GPIO_SCL_OUTP);}void I2C_SDA_Mode(u8 v_mode){ if(v_mode) { s3c2410_gpio_cfgpin(GPIO_SDA, GPIO_SDA_OUTP); } else { s3c2410_gpio_cfgpin(GPIO_SDA, GPIO_SDA_INP); }}u8 I2C_SDA_Read(void){ return s3c2410_gpio_getpin(GPIO_SDA); }void I2C_SDA_Output(u8 value){ if(value) { s3c2410_gpio_setpin(GPIO_SDA,value); } else { s3c2410_gpio_setpin(GPIO_SDA,value ); }}void I2C_SCL_Output(u8 value){ if(value) { s3c2410_gpio_setpin(GPIO_SCL,value); } else { s3c2410_gpio_setpin(GPIO_SCL,value ); }}//static u8 Flag_Timeout;void I2C_Init(void){ I2C_SDA_Output(1); I2C_SCL_Output(1);}void I2C_Wait(void){ u16 i; for(i=0;i<0x1000;i++); for(i=0;i<200;i++);}void I2C_Start(void) { I2C_SDA_Output(1); I2C_SCL_Output(1); I2C_Wait(); I2C_SDA_Output(0); I2C_Wait(); I2C_SCL_Output(0);}void I2C_Stop(void) { I2C_SDA_Output(0); I2C_Wait(); I2C_SCL_Output(1); I2C_Wait(); I2C_SDA_Output(1);}u8 I2C_Send_Byte(u8 bytedata) { u8 i; u8 ack; I2C_SDA_Mode(1);//自己添加 I2C_SCL_OUTP(); for (i = 0; i < 8; i++) { if (bytedata & 0x80) { I2C_SDA_Output(1); } else { I2C_SDA_Output(0); } bytedata <<= 1; I2C_Wait(); I2C_SCL_Output(1); I2C_Wait(); I2C_SCL_Output(0); I2C_Wait(); } I2C_SDA_Output(1); I2C_Wait(); I2C_SDA_Mode(0); I2C_SCL_Output(1); I2C_Wait(); s3c2410_gpio_setpin(GPIO_SDA,0); ack = I2C_SDA_Read(); printk("ack is:%x\n",ack); I2C_SDA_Mode(1); I2C_SCL_Output(0); I2C_Wait(); return ack; }u8 I2C_Receive_Byte(void) { u8 i; u8 bytedata = 0; u8 temp; I2C_SDA_Mode(0); for ( i = 0; i < 8; i++) { I2C_SCL_Output(1); I2C_Wait(); bytedata <<= 1; temp = I2C_SDA_Read(); if (temp) bytedata |= 0x01; I2C_SCL_Output(0); I2C_Wait(); } I2C_SDA_Mode(1); return bytedata;}void Send_Ack(u8 ack) { I2C_SDA_Output(ack); I2C_SCL_Output(1); I2C_Wait(); I2C_SCL_Output(0);}u8 I2C_Byte_Write(u8 device_ID,u8 address,u8 bytedata){ u8 ack; printk("device_ID is:%x\n",device_ID); printk("address is:%x\n",address); printk("date is:%x\n",bytedata); I2C_Start(); ack = I2C_Send_Byte(device_ID); if (ack) { I2C_Stop(); return 0; } ack = I2C_Send_Byte(address); if (ack) { I2C_Stop(); return 0; } ack = I2C_Send_Byte(bytedata); if (ack) { I2C_Stop(); return 0; } I2C_Stop(); I2C_Wait(); return ack;}u8 I2C_Byte_Read(u8 device_ID,u8 address){ u8 bytedata; I2C_Start(); I2C_Send_Byte(device_ID); I2C_Send_Byte(address); I2C_Start(); I2C_Send_Byte(device_ID+1); bytedata = I2C_Receive_Byte(); Send_Ack(1); I2C_Stop(); return bytedata;}void I2C_Test(u8 device_ID,u8 address){ int i; I2C_Init(); I2C_Byte_Write(device_ID,address,0x54); for(i = 0; i < 50; i++);}static int s3c2410_i2c_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg){ u8 k; switch(cmd) { case 0 : I2C_Test(0xa0,0x00); break; case 1 : k=I2C_Byte_Read(0xa0,0x00); printk("k is:%x\n",k); return k; break; default : return -EINVAL; } return 0;} static struct file_operations dev_fops={ .owner = THIS_MODULE, .ioctl = s3c2410_i2c_ioctl,};static struct miscdevice misc = { .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &dev_fops,};static int __init dev_init(void){ int ret; ret = misc_register(&misc); printk (DEVICE_NAME"\tinitialized\n"); return ret;}static void __exit dev_exit(void){ misc_deregister(&misc);}module_init(dev_init);module_exit(dev_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("WEI XIAO HUA");