免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1827 | 回复: 9
打印 上一主题 下一主题

各位高手帮我看一下我写的模拟I2C接收的驱动有什么问题? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-06-04 09:52 |只看该作者 |倒序浏览
#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

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;
        I2C_SCL = 0x0;
        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)
{
       
}

/**//*------------------------------------------------------------------------
----
调用方式: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);

论坛徽章:
5
2 [报告]
发表于 2009-06-04 09:57 |只看该作者
是你写的吗?

先说说你的代码实现了什么吧?

论坛徽章:
5
3 [报告]
发表于 2009-06-04 10:07 |只看该作者
LZ自己写的代码, 强烈要求LZ能解释一下.

论坛徽章:
0
4 [报告]
发表于 2009-06-04 10:22 |只看该作者
哪儿映射地址了

论坛徽章:
0
5 [报告]
发表于 2009-06-04 11:06 |只看该作者
就是通过两根GPIO口来接收I2C的数据啊,当I2C—SCL为高的时候读I2C_SDA口啊。

论坛徽章:
5
6 [报告]
发表于 2009-06-04 11:14 |只看该作者

回复 #5 kyzlin 的帖子

SCL为高时, 就读SDA? 协议没有这样说阿.

论坛徽章:
5
7 [报告]
发表于 2009-06-04 11:16 |只看该作者
你的Start, Stop检测呢?
地址检测呢?
ACK/NAK应答呢?
时钟同步呢?
总线arbitration呢?

通通没看到!

论坛徽章:
5
8 [报告]
发表于 2009-06-04 11:20 |只看该作者
上面是基本的,
还可以扩展: Restart, 总线死锁检测, 广播地址, 8/16位地址

论坛徽章:
0
9 [报告]
发表于 2009-06-04 11:33 |只看该作者
这个是模拟的Slave,不用START,就是被动接收

论坛徽章:
5
10 [报告]
发表于 2009-06-04 13:02 |只看该作者

回复 #9 kyzlin 的帖子

被动接收, 什么时候算开始? 什么时候算结束?

即使Slave, 也要接收到Start, 才开始接收数据, 是不?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP