免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: kyzlin
打印 上一主题 下一主题

哪位高手有GPIO模拟I2C的程序(2410)? [复制链接]

论坛徽章:
0
11 [报告]
发表于 2009-06-03 16:49 |只看该作者

我自己写了个驱动,大家看看有没有什么问题

#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/delay.h>
#include <linux/fcntl.h>
#include <asm/uaccess.h>

#define uchar unsigned char

#define AUCUBA_GPIO_C_BASE                (0xf60700000)          //GPIO C Address Base

#define I2C_SDA                           (*(volatile unsigned short int *)(AUCUBA_GPIO_C_BASE+0x00)     //GPIO_C1 SDA
#define I2C_SCL                           (*(volatile unsigned short int *)(AUCUBA_GPIO_C_BASE+0x004))     //GPIO_C0 SCL
#define GPIODIR                                (*(volatile unsigned short int *)(AUCUBA_GPIO_C_BASE+0x400))     //GPIO direction
#define GPIOFUNCTION                        (*(volatile unsigned short int *)(AUCUBA_GPIO_C_BASE+0x420))     //GPIO Mode select
#define OUT_IN                                        (GPIODIR |= 0x1)             //C1 input,C0 output
#define IN_OUT                                        (GPIODIR |= 0x2)                        //C1 output,C0 input
#define IN_IN                             (GPIODIR |= 0x0)             //C1 ,C0 input

#define I2C_READ   0x01

/*typedef enum {
        I2C_READ
} MU_ioctl_t; */

/*struct   bit   
{   
        unsigned char  bit   :   1             //定义一个变量bit,长度为1为.   
}; */

static int major = 250;
char MU_name[] = "I2C_input";

#define SomeNOP() udelay(300);


/**//*-----------------------------------------------------------------------
----
调用方式:uchar I2CReceive(void)
函数说明:私有函数,I2C专用
------------------------------------------------------------------------------
---*/
unsigned char I2CReceiveByte(void)
{
        uchar BitCnt;
        uchar Retc;
        uchar errtime;
        uchar RSDA;
        Retc=0x00;
        GPIODIR |= 0x00;
        GPIOFUNCTION &= ~0x00;
        for(BitCnt=0;BitCnt<8;BitCnt++)
        {
                  Retc=Retc<<1;
                  errtime=255;
                  while(!I2C_SCL)
                  {
                    errtime--;
                   if(!errtime) return(0xff);    /*超时返回*/
                  }  
                  while(I2C_SCL)
                  {  
                   RSDA=I2C_SDA;
                   if(RSDA==1) Retc="Retc"+1;
                   errtime=255;
                   while(I2C_SCL)
                           {
                             errtime--;
                           if(!errtime) return(0xff); /*超时返回*/
                           }
                   break;
                 }
        }
        return(Retc);
}

//****************************************************
void ACK(void)
{
        // while(READ_SCL);
        //while(!READ_SCL);
        //P3DIR |= SDA; //第9个CLK变高的情况下,SDA输出0
        //while(READ_SCL);
        //P3DIR &= ~SDA; //第9个CLK变低的情况下,SDA输出1
}

/**//*------------------------------------------------------------------------
----
调用方式:MU_ioctl()
函数说明:ioctl函数
----------------------------------------------------------------------------
---*/
static int MU_ioctl(struct inode *s_node,struct file *s_file,unsigned int cmd,unsigned long arg)
{
   int retv;
   unsigned char data;
   switch(cmd)
       {
                case I2C_READ:
                                //I2CInit();
                                //I2CStart();
                                data = I2CReceiveByte();
                                put_user(data,(unsigned long*)arg);
                                data = 0;
                                //printk(" \n",data);
                                break;

                default:
                        break;
       }
           return 0;
}

static struct file_operations mu_fops=
{
  ioctl : MU_ioctl
};



static int __init MUdrv_init_module(void)
{
  int retv;
  retv=register_chrdev(major,MU_name,&mu_fops);
  if(retv<0)
    {
      printk("<1>register fail!\n";
      return retv;
    }
  if(major==0)
       major=retv;
   printk("major=%d\n",major);
   printk("<1>hello MUdrv!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
  
   return 0;
}
   
static void __exit MUdrv_cleanup(void)
{
   int retv;
   retv=unregister_chrdev(major,MU_name);
   if(retv<0)
      {
         printk("<1>unreginster fail!\n";
         return;
      }
   printk("<1>MUdrv:good_bye!\n";
}

module_init(MUdrv_init_module);
module_exit(MUdrv_cleanup);
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP