⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at24c01a.c

📁 开发环境为uClinux2.4.x+s3c44b0。此程序以字节方式对IIC器件进行读写。通过硬件测试
💻 C
字号:


/*======================================================
*
*   File Name: 
*   ---------
*   at24c01a.c  
*
*
*   Author:
*   -------
*   zhang dahai
*
*   Email:
*   ------
*   olivercheung@126.com
*
*   QQ & MSN;
*   ---------
*   334654529, olivercheung2005@yahoo.com.cn
*
*   Modification History:
*   -----------------
*   2006-8-23(21:09), zhang dahai, created.
*
*
======================================================*/

#ifndef __KERNEL__
#define __KERNEL__
#endif

/* includes */

#include <linux/kernel.h>       /* printk() */
#include <linux/module.h>       /*this is a kernel module, so ....*/
#include <linux/interrupt.h>
#include <linux/init.h>         /*module_init, module_exit, etc*/
#include <linux/types.h>        /* size_t */
#include <linux/sched.h>        /* current and everything */
#include <linux/fs.h>           /*register_chrdev, file etc*/

#include <asm/uaccess.h>        /*copy_to_user, copy_from_user*/
#include <asm/hardware.h>       	
#include <asm/irq.h>            /*request_irq, etc*/
#include <asm/io.h>

#include "at24c01a.h"

/*===========================================*/
/*                                         defines                                             */
/*===========================================*/

static unsigned char slvAddr;

static unsigned char ack = 0 ;

/*===========================================*/
/*                                          globals                                            */
/*===========================================*/

#define                 IRQ_IIC     INT_IIC

static char *           dev_idkp = IIC_NAME;        /*for request_irq()*/

/*===========================================*/
/*                                          functiona                                          */
/*===========================================*/

void delay( void )
{
    unsigned char i ;
    for( i = 0 ; i < 100 ; i ++ )       
    {
        ;
    } 
}

static ssize_t at24c01a_read(struct file *filp, char *buf, size_t count, loff_t *l)
{
    char readData ;
    unsigned char readAddress ;
    
    
    readAddress = count ;
    
    //---------send control byte-----------
#ifdef DEBUG
    printk("enter at2410a_read( )\n");
    printk("send control byte.\n");
#endif  
    slvAddr = 0xa0;
    IICDS = slvAddr;  // 0xa0
    IICSTAT=0xf0;   // Master Tx,Start


#ifdef DEBUG
    printk("wait ACK\n");
#endif
    while( ack == 0 ) ;
    ack = 0 ;
    
    //------------send address------------
#ifdef DEBUG
    printk("send address\n");
#endif  
    IICDS = readAddress;
    IICCON = 0xaf;     // resumes IIC operation.

#ifdef DEBUG
    printk("wait ACK\n");
#endif 
    while( ack == 0 ) ;
    ack = 0 ;   
  
    //-----------send control byte---------
#ifdef DEBUG
    printk("send control byte\n");
#endif      
    IICDS = slvAddr|0x01;  // 0xa1:R
    IICSTAT=0xb0;    // Master Rx,Start
    IICCON=0xaf;     // resumes IIC operation.   

#ifdef DEBUG
    printk("wait ACK\n");
#endif  
    while( ack == 0 ) ;
    ack = 0 ;
 
#ifdef DEBUG
    printk("READ \n");
#endif    
  
    readData = IICDS;
    
#ifdef DEBUG
    printk("readData = 0x%x\n",readData );
#endif

    //-------------Loop Start------------
#ifdef DEBUG
    printk("-Loop Start\n" );
#endif  
    IICCON = 0xaf & (~0x80) ;
    
    

#ifdef DEBUG
    printk("wait ACK\n");
#endif     
    while( ack == 0 ) ;
    ack = 0 ;
 
    //-------------get data ------------
#ifdef DEBUG
    printk("READ \n");
#endif     
    readData = IICDS;
#ifdef DEBUG
    printk("readData = 0x%x\n",readData );
#endif
    //-------Loop End--------
#ifdef DEBUG
    printk("-Loop end\n" );
#endif  
    IICSTAT = 0x90;
    IICCON =  0xaf;
    
#ifdef DEBUG
    printk("coping Data from kernel to user......");
#endif      

    copy_to_user( buf , &readData , 1 );
    
#ifdef DEBUG
    printk("done\n");
#endif 

    return 1 ;
}


static ssize_t  at24c01a_write(struct file *filp, const char *buf, size_t count, loff_t *l)
{
    unsigned char i = 0 ;
    unsigned char writeData[2]  ;
    
#ifdef DEBUG
    printk("enter at24c01a_write()\n");

    printk("coping Data from user to kernel, thery are:\n");
#endif

    copy_from_user( writeData , buf , count ) ;

#ifdef DEBUG
    for( i = 0 ; i < count ; i ++ )
    {
        printk("0x%x ", writeData[ i ]);
    }
#endif

    // ---------send control byte---------
#ifdef DEBUG
    printk("send control byte\n");
#endif
    slvAddr = 0xa0;
    IICDS = slvAddr;  // 0xa0
    IICSTAT=0xf0;    // Master Tx,Start

    //-----------wait ACK---------------
#ifdef DEBUG
    printk("wait ACK\n");
#endif
    while( ack == 0 ) ;
    ack = 0 ;    

    //-----------send address--------------
#ifdef DEBUG
    printk("send address\n");
#endif
    IICDS = writeData[ 0 ];
    IICCON = 0xaf;     // resumes IIC operation.
  
    //------------wait ACK---------------
#ifdef DEBUG
    printk("wait ACK\n");
#endif
    while( ack == 0 ) ;
    ack = 0 ;    
 
    //-------------send data -------------
#ifdef DEBUG
    printk("send data\n");
#endif
    IICDS = writeData[ 1 ] ; //0x69;        //Test
    IICCON = 0xaf;     // resumes IIC operation.
    
    //-------------wait ACK    ----------
#ifdef DEBUG
    printk("wait ACK\n");
#endif
    while( ack == 0 ) ;
    ack = 0 ;    

//-------------end send---------------
#ifdef DEBUG
    printk("end send\n");
#endif
    IICSTAT = 0xd0;  // stop Master Tx condition
    IICCON = 0xaf;   // resumes IIC operation.
    
//--------wait until stop condtion is in effect.------
#ifdef DEBUG
    printk("wait until stop condtion is in effect.\n");
#endif
    delay();
    
#ifdef DEBUG
    printk("exit at24c01a_write()\n\n");
#endif    
}

static int at24c01a_open(struct inode *inode, struct file *filp)
{
    int ret;
    
    if ((ret = request_irq( IRQ_IIC, at24c01a_handler, SA_INTERRUPT, 
                        IIC_NAME, dev_idkp)))
    {
        printk("at24c01a interrrupt: failed to register IRQ\n");
        
        free_irq(IRQ_IIC, dev_idkp);
        
        return ret;
    }

#ifdef DEBUG
    printk("Successful to open AT24C01A!\n");
#endif

    disable_irq( IRQ_IIC );                         /*disable at24c01a interrupt on ARM */

    IICADD = 0x10;                                  /* S3C44B0X slave address*/ 

    IICCON = ( 1 << 7 )|( 0 << 6 )|( 1 << 5 )|( 0xf );  /*Enable interrupt, IICCLK=MCLK/16, Enable ACK,clear pending*/
                                                    /*66Mhz/16/(15+1) = 257.8Khz  */
                    					
    IICSTAT = 0x10 ;                                /* Enable RX/TX*/

    enable_irq( IRQ_IIC );                          /*enable at24c01a interrupt on ARM*/
    
    MOD_INC_USE_COUNT;  	

    return 0;
}

static int at24c01a_release(struct inode *inode, struct file *filp)
{
    free_irq(IRQ_IIC, dev_idkp);	
    
    IICSTAT = 0;            /*Disable IIC*/

    MOD_DEC_USE_COUNT;  

#ifdef DEBUG
    printk("Successful to close AT24C01A!\n");
#endif  
    return 0;
}

static void at24c01a_handler(int irq, void *dev_idkp, struct pt_regs *regs)
{
#ifdef DEBUG
    printk("enter at24c01a_handler()\n");
#endif 
    
    //wake_up_interruptible(&iic_queue);
    ack = 1 ;
    I_ISPC=BIT_IIC;
    
#ifdef DEBUG
    printk("exit at24c01a_handler()\n\n");
#endif    
}

int __init at24c01a_init(void)
{
    int ret;

    /*register the char device*/
    if ((ret=register_chrdev(IIC_MAJOR, IIC_NAME, &at24c01a_fops))!=0)
    {
        printk("Failed to register "IIC_NAME "\n"); 
        return ret;
    }

#ifdef DEBUG        
    printk("AT24C01A driver initialized\n");
#endif

    return 0;
}

void __exit at24c01a_cleanup(void)
{

    //free_irq(IRQ_IIC, dev_idkp);  

    unregister_chrdev(IIC_MAJOR, IIC_NAME); 
    
#ifdef DEBUG
    printk("AT24C01A has been removed\n");
#endif

}

module_init(at24c01a_init);  
module_exit(at24c01a_cleanup);

EXPORT_NO_SYMBOLS;

MODULE_DESCRIPTION("The driver for AT24C01A(IIC)");
MODULE_SUPPORTED_DEVICE("uClinux 2.4.x Digital Jet Printer Machine");
MODULE_AUTHOR("Zhang Dahai");
MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -