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


  • 相关阅读:
    考研讲座笔记——张雪峰
    【极简版】OpenGL 超级宝典(第五版)环境配置 VS2010
    OpenGL编程指南(第九版) Tiangles 学习笔记
    qt学习笔记
    郑州大学2018新生训练赛第十场题解
    Win10 中将网页转换成pdf的简便方法
    Kali Linux ——在无网络情况下安装无线网卡驱动
    成环的概率dp(初级) zoj 3329
    概率dp的边界处理 POJ 2096
    node连接mysql生成接口,vue通过接口实现数据的增删改查(一)
  • 原文地址:https://www.cnblogs.com/yuzaipiaofei/p/4124348.html
Copyright © 2020-2023  润新知