免费注册 查看新帖 |

Chinaunix

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

还是关于IIC驱动问题! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-08 13:28 |只看该作者 |倒序浏览
这是程序驱动!
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/delay.h>
#include <asm-generic/errno-base.h>
#include <asm/arch-s3c2410/regs-gpio.h>
#include <asm/arch-s3c2410/regs-iic.h>
#include <asm/hardware.h>
#include <asm/io.h>
#define  DEV_ID  107
#define  DEV_NAME  "2402_RW"
#define  IICCON  0x54000000
#define  IICSTAT 0x54000004
#define  IICDS   0x5400000c
#define  IICADD  0x54000008
#define  IICLC   0x54000010
#define CLKCON   0x4c00000C
static void *S3C2402_IICSTAT;
static void *S3C2402_IICCON;
static void *S3C2402_IICDS;
static void *S3C2402_IICADD;
static void *S3C2402_IICLC;
static void *CLK_CON;
static int open_2402(struct inode * inode, struct file * file)
{   int cmmd,b;
    writel(0xc0000,S3C2410_GPEUP);
    s3c2410_gpio_cfgpin(S3C2410_GPE14,S3C2410_GPE14_IICSCL);
    s3c2410_gpio_cfgpin(S3C2410_GPE15,S3C2410_GPE15_IICSDA);
    S3C2402_IICCON=ioremap(IICCON,0x00000004);
        S3C2402_IICSTAT=ioremap(IICSTAT,0x00000004);
        S3C2402_IICDS=ioremap(IICDS,0x00000004);
        S3C2402_IICADD=ioremap(IICADD,0x00000004);
        S3C2402_IICLC=ioremap(IICLC,0X00000004);
        CLK_CON=ioremap(CLKCON,0X00000004);
        writel(0xf3eb70,CLK_CON);
        cmmd=((S3C2410_IICCON_ACKEN)|(S3C2410_IICCON_TXDIV_16)|(S3C2410_IICCON_IRQEN)|(0x0f));
        writel(cmmd,S3C2402_IICCON);
        b=readl(S3C2402_IICCON);
        printk("b=%x\n",b);
        writel(0x10,S3C2402_IICADD);
        writel(0x10,S3C2402_IICSTAT);
        writel((S3C2410_IICLC_FILTER_ON|S3C2410_IICLC_SDA_DELAY5),S3C2402_IICLC);
        return 0;
     }
static int  write_2402(struct file * file, const char __user * userbuf,size_t count, loff_t * off)
{   
                                                                                 /* (   写)  开始传输信号*/
        writel(0xa0,S3C2402_IICDS);
        writel(0xf0,S3C2402_IICSTAT);
    while(!(readl(S3C2402_IICCON))&S3C2410_IICCON_IRQPEND);                      /*等待发送完毕,查询*/
        writel(0x00,S3C2402_IICDS);
    writel(((readl(S3C2402_IICCON))&(~S3C2410_IICCON_IRQPEND)),S3C2402_IICCON);  /*清除发送标志位*/
        while(!(readl(S3C2402_IICCON))&S3C2410_IICCON_IRQPEND);                       /*等待发送完毕,查询*/
        writel(*userbuf,S3C2402_IICDS);
    writel(((readl(S3C2402_IICCON))&(~S3C2410_IICCON_IRQPEND)),S3C2402_IICCON);  /*清除发送标志位*/
        while(!(readl(S3C2402_IICCON))&S3C2410_IICCON_IRQPEND);                       /*等待发送完毕,查询*/
        writel(0xd0,S3C2402_IICSTAT);                                                 /*  (  写)  停止传输信号*/
    writel(((readl(S3C2402_IICCON))&(~S3C2410_IICCON_IRQPEND)),S3C2402_IICCON);  /*清除发送标志位*/
        mdelay(5);
        return count;
         }
static int  read_2402 (struct file * file, char __user * userbuf, size_t count, loff_t * off)
{   int a;
    writel(0xa0,S3C2402_IICDS);  
        writel(0xf0,S3C2402_IICSTAT);
        while(!(readl(S3C2402_IICCON))&S3C2410_IICCON_IRQPEND);                        /*等待发送完毕,查询*/
    writel(0x00,S3C2402_IICDS);
    writel(((readl(S3C2402_IICCON))&(~S3C2410_IICCON_IRQPEND)),S3C2402_IICCON);
        while(!(readl(S3C2402_IICCON))&S3C2410_IICCON_IRQPEND);
        writel(0xa1,S3C2402_IICDS);
    writel(0xb0,S3C2402_IICSTAT);
        writel(((readl(S3C2402_IICCON))&(~S3C2410_IICCON_IRQPEND)),S3C2402_IICCON);
        while(!(readl(S3C2402_IICCON))&S3C2410_IICCON_IRQPEND);
        a=readl(S3C2402_IICDS);
        printk("a=%x\n",a);
    writel(0x2f,S3C2402_IICCON);
        while(!(readl(S3C2402_IICCON))&S3C2410_IICCON_IRQPEND);                         /*等待发送完毕,查询*/
        *userbuf=readl(S3C2402_IICDS);
        writel(0x90,S3C2402_IICSTAT);                                                    /*  (  读)  停止传输信号*/
    writel(0xaf,S3C2402_IICCON);
        mdelay(5);
        return count;
         }
                        
static struct file_operations test_2402 ={
.open    =   open_2402,
.write   =   write_2402,
.read         =   read_2402,
};
static int __init init_2402(void)
{ int result;
  result=register_chrdev(DEV_ID,DEV_NAME,&test_2402);
  if (result<0)
          { printk ("the derive register is fail!!!\n");
            return ENODEV;
             }
  else
          { printk ("the derive register is sucess!!!\n");
      devfs_mk_cdev(MKDEV(DEV_ID,0),S_IFCHR | S_IRUSR | S_IWUSR,"2402_RW");
            return result;
            }
   }
static void __exit exit_2402(void)
{ unregister_chrdev(DEV_ID,DEV_NAME);
  devfs_remove(DEV_NAME);
  printk ("the derive is unregister\n");
   }
module_init(init_2402);
module_exit(exit_2402);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("KANG");
MODULE_DESCRIPTION("2402_READ_WRITE");




while(!(readl(S3C2402_IICCON))&S3C2410_IICCON_IRQPEND);                        /*等待发送完毕,查询*/
是采用查询方式!等待数据发送完!S3C2402_IICCON中的第5位置"1"发送接收一个字节完毕!
writel(((readl(S3C2402_IICCON))&(~S3C2410_IICCON_IRQPEND)),S3C2402_IICCON);
这条语句清除S3C2402_IICCON第5位的接收发送数据标志位!"0"

不知道为什么老是在
writel(0xa1,S3C2402_IICDS);
    writel(0xb0,S3C2402_IICSTAT);
        writel(((readl(S3C2402_IICCON))&(~S3C2410_IICCON_IRQPEND)),S3C2402_IICCON);
        while(!(readl(S3C2402_IICCON))&S3C2410_IICCON_IRQPEND);
        a=readl(S3C2402_IICDS);
        printk("a=%x\n",a);
    writel(0x2f,S3C2402_IICCON);
        while(!(readl(S3C2402_IICCON))&S3C2410_IICCON_IRQPEND);                         /*等待发送完毕,查询*/
        *userbuf=readl(S3C2402_IICDS);
这几条语句中时候读到的数据总是为A1也是那个读的命令!按理应该读到的数据应该对应我开写进去的数据!
前辈!!帮我看一下行!
之前也在发过此贴!之前是因为CLKCON没有开IIC!这个时钟被禁用了!现在打了,可以读出来的数据又不对!

论坛徽章:
3
金牛座
日期:2014-06-14 22:04:062015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:45
2 [报告]
发表于 2009-02-08 15:24 |只看该作者

回复 #1 shuiyu123 的帖子

我觉得你应该仔细看一下datasheet,然后对照一下你的现象来定位问题。
你这里没有用到内存映射等知识,所以,应该不是系统造成的问题,很可能是你设置的问题。

论坛徽章:
0
3 [报告]
发表于 2009-03-02 01:08 |只看该作者
你写得太麻烦了,没有看kernel代码,它已经有框架了,你可以直接使用,我没有看到你的datasheet,不知道那几个寄存器是什么意思,不过我用gpio写过一个,两个寄存器就足够了,好好看看datasheet
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP