Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1264341
  • 博文数量: 404
  • 博客积分: 10011
  • 博客等级: 上将
  • 技术积分: 5382
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-03 16:29
文章存档

2010年(40)

2009年(140)

2008年(224)

我的朋友

分类: LINUX

2008-09-26 11:06:25

/*
*        2.6
内核IIC驱动程序
*
*        1.
四种模式的IIC驱动编写介绍
*        2.
一个完整的IIC驱动(从器件接收模式,并且是裸写驱动)
*        
*        1.1
开启从器件接收模式的示例
*        R_IICCON = 0xE2; //
使能ACK,使能中断
*        R_IICADD = 0xAA; //
从器件地址
*        R_IICSTAT = 0x10; //
设置从器件接收模式
*        
*        
进入中断处理,读收数据:
*        unit8_t ch = R_IICDS & 0xff; //
读取数据寄存
*        R_IICCON &= 0xEF; //
清除IICCON[4]恢复中断响应
*        RET;
*        
*        1.2
开启从器件发送模式的示例
*        R_IICCON = 0xE2; //
使能ACK,使能中断
*        R_IICADD = 0xAA; //
从器件地址
*        R_IICSTAT = 0x50; //
设置从器件接收模式
*        
*        
进入中断处理,发送数据:
*        unit8_t ch = extern_buffer[i]; //
取得待发送到从器件的数据
*        R_IICDS = ch; //
写入数据到IICDS
*        R_IICCON &= 0xEF; //
清除IICCON[4]恢复中断响应
*        RET;
*        
*        
以切换模式的方式结束发送。
*        
*        1.3
开启主器件发送模式的示例
*        R_IICCON = 0xE2; //
使能ACK,使能中断
*        R_IICSTAT = 0xD0; //
设置主器件发送模式
*        R_IICDS = 0xD0; //
写入从器件地址到IICDS寄存器
*        R_IICSTAT = 0xF0; //
送出IICDS中的数据
*        
*        ACK
并进入中断处理:
*        uint8_t ch = extern_buffer[i]; //
取得待发送到从器件的数据
*        R_IICDS = ch; //
再次写入数据到IICDS
*        R_IICCON &= 0xEF; //
清除IICCON[4]恢复中断响应

*        
结束发送:
*        R_IICSTAT = 0xD0; //
IICSTAT[5]0,产生停止条件
*        
*        1.4
开启主器件接收模式的示例
*        R_IICCON = 0xE2; //
使能ACK,使能中断
*        R_IICSTAT = 0x90; //
设置主器件接收模式
*        R_IICDS = 0xD0; //
写入从器件地址到 IICDS
*        R_IICSTAT = 0xB0; //
送出IICDS中的数据
*        
*        ACK
并进入中断处理:
*        uint8_t ch = R_IICDS & 0xFF; //
读取一个八位序列
*        R_IICCON &= 0xEF; //
清除IICCON[4]恢复中断响应
*        
*        
结束接收:
*        R_IICSTAT = 0x90; //
IICSTAT[5]0,产生停止条件
*/

2.1 驱动源代码

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/poll.h>
#include <linux/wait.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <asm/arch/irqs.h>

#define DEVICE "TEST_IIC"
#define DATA_LEN 6

int major = 233;
int minor = 0;
void *R_GPECON,*R_GPEUP,*R_IICCON,*R_IICSTAT,*R_IICADD,*R_IICDS;

int IIC_open(struct inode *, struct file *);
int IIC_release(struct inode *, struct file *);
ssize_t IIC_read
(struct file *file, char* buf, size_t count, loff_t *f_pos);
unsigned int IIC_poll(struct file* file, poll_table* wait);
irqreturn_t interrupt_handle
( int irq, void* dev_id, struct pt_regs* regs );

static void address_map(void)
{
#define IIC_BASE (0x54000000)
#define IIC_GPECON ( IIC_BASE + 0x40 )
#define IIC_GPEUP ( IIC_BASE + 0x48 )
#define IIC_CON ( IIC_BASE + 0x0 )
#define IIC_STAT ( IIC_BASE + 0x4 )
#define IIC_ADDR ( IIC_BASE + 0x8 )
#define IIC_DS ( IIC_BASE + 0xC )
        R_GPECON
= ioremap(IIC_GPECON,4);
        R_GPEUP
= ioremap(IIC_GPEUP ,4);
        R_IICCON
= ioremap(IIC_CON ,4);
        R_IICSTAT
= ioremap(IIC_STAT ,4);
        R_IICADD
= ioremap(IIC_ADDR ,4);
        R_IICDS
= ioremap(IIC_DS ,4);
}

static void address_unmap(void)
{
        iounmap
( R_GPECON );
        iounmap
( R_GPEUP );
        iounmap
( R_IICCON );
        iounmap
( R_IICSTAT );
        iounmap
( R_IICADD );
        iounmap
( R_IICDS );
}

static struct file_operations fops = {
        owner
: THIS_MODULE,
        
read: IIC_read,
        
open: IIC_open,
        release
: IIC_release,
        poll
: IIC_poll,
};

阅读(919) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~