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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值