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

📄 2410iic.c

📁 一个嵌入linux下s3c2410通过i2c读写eerom的驱动程序和应用程序。
💻 C
字号:
//====================================================================// File Name : 2410iic.c// Function  : S3C2410 IIC-bus Master Tx/Rx mode Program// Date      : July 16, 2004// Version   : 0.0//====================================================================#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/delay.h>#include <linux/signal.h>#include <linux/sched.h>#include <linux/timer.h>#include <linux/interrupt.h>#include <asm/irq.h>#include <linux/vmalloc.h>#include "khead.h"#define IICBUFSIZE 0x20#define BIT_IIC        (0x1<<27)#define rGPECON    (*(volatile unsigned long *)r_GPECON) //Port E control#define rGPEUP     (*(volatile unsigned long *)r_GPEUP) //Pull-up control E#define rIICCON  (*(volatile unsigned char *)r_IICCON) //IIC control#define rIICSTAT (*(volatile unsigned char *)r_IICSTAT) //IIC status#define rIICADD  (*(volatile unsigned char *)r_IICADD) //IIC address#define rIICDS   (*(volatile unsigned char *)r_IICDS) //IIC data shift#define WRDATA      (1)#define POLLACK     (2)#define RDDATA      (3)#define SETRDADDR   (4)#define Uart_Printf PDEBUG#define U8 unsigned char#define U32 unsigned intstatic unsigned char _iicData[IICBUFSIZE];static volatile int _iicDataCount;static volatile int _iicStatus;static volatile int _iicMode;static int _iicPt;extern void Test_Iic(void);extern void Init_Iic(void);extern void _Wr2410Iic_E2PROM(U32 slvAddr,U32 addr,U8 *buffer,U32 length);extern void _Wr2410Iic(U32 slvAddr,U32 addr,U8 wdata);extern void _Rd2410Iic_E2PROM(U32 slvAddr,U32 addr,U8 *buffer,U32 length);void Run_IicPoll(void);void IicPoll(void);int address_map(void);	unsigned long r_GPECON,r_GPEUP;unsigned long r_IICCON,r_IICSTAT,r_IICADD,r_IICDS;//=================================================================== //*********************[ address_map ]*********************************int address_map(void){	r_GPECON	=__ioremap(0x56000040,4,0);	r_GPEUP		=__ioremap(0x56000048,4,0);	r_IICCON	=__ioremap(0x54000000,4,0);	r_IICSTAT	=__ioremap(0x54000004,4,0);	r_IICADD	=__ioremap(0x54000008,4,0);	r_IICDS		=__ioremap(0x5400000c,4,0);	return 0;}//*********************[ Delay ]*********************************void Delay(int times){	udelay(1000);}//**************[ _Wr2410Iic ]*****************************************void _Wr2410Iic_E2PROM(U32 slvAddr,U32 addr,U8 *buffer,U32 length){     //X1227 Page Write mode     int i = 0;    _iicMode      = WRDATA;    _iicPt        = 0;    _iicData[0]   = addr/256;    _iicData[1]   = addr;    for(i = 2; i<2+length; i++)    {    	_iicData[i]   = buffer[i-2];    }        _iicDataCount = length+2;         rIICDS        = slvAddr&0xfe;                  //Master Tx mode, Start(Write), IIC-bus data output enable      //Bus arbitration sucessful, Address as slave status flag Cleared,      //Address zero status flag cleared, Last received bit is 0    rIICSTAT      = 0xf0;            //Clearing the pending bit isn't needed because the pending bit has been cleared.    while(_iicDataCount!=-1)       Run_IicPoll();    _iicMode = POLLACK;    while(1)    {        rIICDS     =slvAddr&0xfe;        _iicStatus = 0x100;              //To check if _iicStatus is changed         rIICSTAT   = 0xf0;              //Master Tx, Start, Output Enable, Sucessful, Cleared, Cleared, 0        rIICCON    = 0xaf;              //Resumes IIC operation. 	 while(_iicStatus==0x100)              Run_IicPoll();                      if(!(_iicStatus & 0x1))		PDEBUG("ACK is received\n");        break;                      //When ACK is received    }    rIICSTAT = 0xd0;                    //Master Tx condition, Stop(Write), Output Enable    rIICCON  = 0xaf;                    //Resumes IIC operation.     Delay(1);                           //Wait until stop condtion is in effect.    //Write is completed.}//**************[ _Wr2410_Iic ]*****************************************void _Wr2410Iic(U32 slvAddr,U32 addr,U8 wdata){     //X1227 byte write mode    _iicMode      = WRDATA;    _iicPt        = 0;    _iicData[0]   = addr/256;    _iicData[1]   = addr;    _iicData[2]   = wdata;    _iicDataCount = 3;    rIICDS        = slvAddr&0xfe;      //Master Tx mode, Start(Write), IIC-bus data output enable      //Bus arbitration sucessful, Address as slave status flag Cleared,      //Address zero status flag cleared, Last received bit is 0    rIICSTAT      = 0xf0;      //Clearing the pending bit isn't needed because the pending bit has been cleared.    while(_iicDataCount!=-1)       Run_IicPoll();    _iicMode = POLLACK;    while(1)    {        rIICDS     =slvAddr&0xfe;        _iicStatus = 0x100;              //To check if _iicStatus is changed        rIICSTAT   = 0xf0;              //Master Tx, Start, Output Enable, Sucessful, Cleared, Cleared, 0        rIICCON    = 0xaf;              //Resumes IIC operation.         while(_iicStatus==0x100)            Run_IicPoll();        if(!(_iicStatus & 0x1))                PDEBUG("ACK is received\n");        break;                      //When ACK is received    }    rIICSTAT = 0xd0;                    //Master Tx condition, Stop(Write), Output Enable    rIICCON  = 0xaf;                    //Resumes IIC operation.    Delay(1);                           //Wait until stop condtion is in effect.    //Write is completed.}		//************************[ _Rd2410Iic ]********************************void _Rd2410Iic_E2PROM(U32 slvAddr,U32 addr,U8 *buffer,U32 length){     //X1227 Random read && Sequential read     int i = 0;     PDEBUG("read---->0\n");    _iicMode      = SETRDADDR;    _iicPt        = 0;    _iicData[0]   = addr/256;    _iicData[1]   = addr;    _iicDataCount = 2;        rIICDS   = slvAddr&0xfe;    rIICSTAT = 0xf0;                    //MasTx,Start      //Clearing the pending bit isn't needed because the pending bit has been cleared.    while(_iicDataCount!=-1)        Run_IicPoll();	    _iicMode      = RDDATA;    _iicPt        = 1;    _iicDataCount = length;        rIICDS   = slvAddr|0x01;    rIICSTAT = 0xb0;                    //Master Rx,Start    rIICCON  = 0xaf;                    //Resumes IIC operation.       while(_iicDataCount!=-1)        Run_IicPoll();    printk("In the Read Function\n");    for(i = 0; i<length;i++)    {		buffer[i] = _iicData[i+2];//		printk("The read num %d is %x\n",i,_iicData[i+2]);    }   	}//**********************[ Run_IicPoll ]*********************************void Run_IicPoll(void){    if(rIICCON & 0x10)                         IicPoll();}           //**********************[IicPoll ]**************************************void IicPoll(void){    U32 iicSt,i;        iicSt = rIICSTAT;     if(iicSt & 0x8){	PDEBUG("bus arbitration is failed\n");			}   //When bus arbitration is failed.    if(iicSt & 0x4){	PDEBUG("matched\n");	}                   //When a slave address is matched with IICADD    if(iicSt & 0x2){	PDEBUG("slave address 0000000b\n");	}                   //When a slave address is 0000000b    if(iicSt & 0x1){	PDEBUG("Ack isn't received\n");	}                   //When ACK isn't received    switch(_iicMode)    {        case POLLACK:		PDEBUG("poll--ACK\n");            _iicStatus = iicSt;            break;        case RDDATA:              PDEBUG("read--ACK\n");            if((_iicDataCount--)==0)            {                _iicData[_iicPt++] = rIICDS;                            rIICSTAT = 0x90;                //Stop MasRx condition                 rIICCON  = 0xaf;                //Resumes IIC operation.                Delay(1);                       //Wait until stop condtion is in effect.                                                //Too long time...                                                 //The pending bit will not be set after issuing stop condition.                break;                }                  _iicData[_iicPt++] = rIICDS;                        //The last data has to be read with no ack.            if((_iicDataCount)==0)                rIICCON = 0x2f;                 //Resumes IIC operation with NOACK.              else                 rIICCON = 0xaf;                 //Resumes IIC operation with ACK            break;        case WRDATA:		PDEBUG("write--ACK\n");            if((_iicDataCount--)==0)            {                rIICSTAT = 0xd0;                //stop MasTx condition                 rIICCON  = 0xaf;                //resumes IIC operation.                Delay(1);                       //wait until stop condtion is in effect.                       //The pending bit will not be set after issuing stop condition.                break;                }		PDEBUG("poll--->write\n");            rIICDS = _iicData[_iicPt++];                    for(i=0;i<10;i++);                  //for setup time until rising edge of IICSCL            rIICCON = 0xaf;                     //resumes IIC operation.            break;        case SETRDADDR:		PDEBUG("SETRDADDR\n");            if((_iicDataCount--)==0)            {                break;                  //IIC operation is stopped because of IICCON[4]                }            rIICDS = _iicData[_iicPt++];            for(i=0;i<10;i++);          //for setup time until rising edge of IICSCL            rIICCON = 0xaf;             //resumes IIC operation.            break;        default:            break;          }}void Init_Iic(void){	address_map();	 	rGPEUP  |= 0xc000;                  //Pull-up disable  	rGPECON |= 0xa00000;                //GPE15:IICSDA , GPE14:IICSCL                //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16        rIICCON  = (1<<7) | (0<<6) | (1<<5) | (0xf);        rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)}void Test_Iic(void){    unsigned int save_E,save_PE;    unsigned char buffer[3],read[3];    unsigned int len,j;//    static U8 rdata;//    static U8 wdata;    static U32 i;    address_map();    save_E   = rGPECON;    save_PE  = rGPEUP;    rGPEUP  |= 0xc000;                  //Pull-up disable    rGPECON |= 0xa00000;                //GPE15:IICSDA , GPE14:IICSCL    //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16    rIICCON  = (1<<7) | (0<<6) | (1<<5) | (0xf);    rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)    _Wr2410Iic(0xde,0x3f,0x02);	    printk("--------->1\n");    buffer[0] = 0x11;    buffer[1] = 0x22;    buffer[2] = 0x33;    len = 3;    i=0x0;     _Wr2410Iic_E2PROM(0xae,i,buffer,len);    for(j = 0; j<len; j++)    {    	printk("The writing data is:%x\n",buffer[j]);    }    printk("--------->2\n");    _Rd2410Iic_E2PROM(0xaf,i,read,len);    for(j = 0; j<len; j++)    {    	printk("The reading data is:%x \n",read[j]);    }    printk("--------->3\n");    rGPECON = save_E;    rGPEUP = save_PE;}

⌨️ 快捷键说明

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