linux gpio模拟i2c

  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_OUTP


void 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");


你可能感兴趣的:(linux gpio模拟i2c)