S3C44b0的IIC(AT24C04)的uclinux驱动
2013-03-11
标签: S3C44B0

看了很多书上写的44b0的IIC的驱动都是很难理解的那种,都是照抄三星的程序的,于是就自己改写了IIC的驱动,我认为这样有助于理解执行的过程,很简单易懂.

/*

*iic.c:

* read and write only one byte for AT24C04

*/

#i nclude

#i nclude

#i nclude

#i nclude

#i nclude

#i nclude

#i nclude

#i nclude

#i nclude

#i nclude "IIC.h"

void vdelay(unsigned short i);

static DECLARE_WAIT_QUEUE_HEAD(wait);

unsigned char WrData= 0 ;

unsigned char RecvData[2] = {0,0};

volatile static unsigned char ack_tag;

volatile static unsigned int addr;

static int IIC_read(struct file *filp,char *buf,size_t count,loff_t *f_pos) //count读取的数量;

{

//printk("read addr %d \n",addr);

/****************** 读** 写入设备地址 **********************/

ack_tag = 0;

CSR_WRITE(rIICDS,0xa0);//设备地址

CSR_WRITE(rIICSTAT,0xf0); //MasTx,start,En Tx/Rx,

wait_event_interruptible(wait, (ack_tag != 0)); //wait the trans complete

ack_tag = 0;

/***************** 读**写入读取的低地址 ************/

CSR_WRITE(rIICDS,(char)addr);//the read address

CSR_WRITE(rIICCON,0xaf); //resume iic operation

wait_event_interruptible(wait, (ack_tag != 0)); //wait the trans complete

ack_tag = 0;

/****************** 读**再次写入设备地址 **********************/

CSR_WRITE(rIICDS,0xa0);//设备地址

CSR_WRITE(rIICSTAT,0xb0); //MasRx,start,En Tx/Rx,

CSR_WRITE(rIICCON,0xaf); //resume iic operation

wait_event_interruptible(wait, (ack_tag != 0)); //wait the trans complete

ack_tag = 0;

/***************** read the data ************************************/

RecvData[1]=CSR_READ(rIICDS);//这次读到的没有用

CSR_WRITE(rIICCON,0x2f);//只读一位

wait_event_interruptible(wait, (ack_tag != 0)); //wait the trans complete

ack_tag = 0;

RecvData[0]=CSR_READ(rIICDS);

printk("read data %d \n",RecvData[0]);

/***************** stop trans ***************************************/

CSR_WRITE(rIICSTAT,0x90); //MasRx,stop,En Tx/Rx,

CSR_WRITE(rIICCON,0xaf); //resume iic operation

vdelay(100);

copy_to_user(buf, &RecvData, sizeof(char));

return (1);

}

static int IIC_write(struct file *filp,char *buf,size_t count,loff_t *f_pos)

{

//unsigned int i;

if(copy_from_user(&WrData, buf, sizeof(char)))

{

printk("error writing, copy_from_user\n");

return -EFAULT;

}

printk("write address %d \n",addr);

printk("write data %d \n",WrData);

/****************** 写** 写入设备地址 **********************/

ack_tag = 0;

CSR_WRITE(rIICDS,0xa0);

CSR_WRITE(rIICSTAT,0xf0); //MasTx,start,En Tx/Rx,

wait_event_interruptible(wait, (ack_tag != 0)); //wait the trans complete

ack_tag = 0;

/***************** 写** 写入存储器的内部地址低位 ************/

CSR_WRITE(rIICDS,(char)addr);//the write high address

CSR_WRITE(rIICCON,0xaf); //resume iic operation

wait_event_interruptible(wait, (ack_tag != 0)); //wait the trans complete

ack_tag = 0;

/***************** write the data ************************************/

CSR_WRITE(rIICDS,WrData);//the write high address

CSR_WRITE(rIICCON,0xaf); //resume iic operation

wait_event_interruptible(wait, (ack_tag != 0)); //wait the trans complete

ack_tag = 0;

/***************** stop trans ***************************************/

CSR_WRITE(rIICSTAT,0xd0); //MasTx,stop,En Tx/Rx,

CSR_WRITE(rIICCON,0xaf); //resume iic operation

vdelay(100);

return (1);

}

static int IIC_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)

{

addr = arg;

return 1;

}

static int IIC_open(struct inode *inode,struct file *filp)

{

MOD_INC_USE_COUNT;

printk("<>someone open iic!\n");

return 0;

}

static int IIC_release(struct inode *inode,struct file *filp)

{

MOD_DEC_USE_COUNT;

printk("<>someone close iic\n");

return 0;

}

static int IIC_select(struct file *file,struct poll_table_struct *wait)

{

return 0;

}

void IIC_handle(int irq,void *dev_id,struct pt_regs *regs)

{

//char rec;

//rec = CSR_READ(rIICDS);

//printk(" \n %d \ n",rec);

CSR_WRITE(rI_ISPC,(CSR_READ(rI_ISPC)|BIT_IIC));// Clear IICPending Bit

ack_tag = 1;

wake_up_interruptible(&wait);

}

void IIC_init(void)

{

int ret;

CSR_WRITE(rPCONF,((CSR_READ(rPCONF)&0xfffffff0)|0xa)); //PF0:IICSCL,PF1:IICSDA

CSR_WRITE(rPUPF,(CSR_READ(rPUPF)|0x3));//禁止内部上拉

CSR_WRITE(rIICCON,0xaf);//(1<<7)|(0<<6)|(1<<5)|(0xf));//Enable interrupt, IICCLK=MCLK/16, Enable ACK

//40Mhz/16/(15+1) = 257Khz

CSR_WRITE(rIICADD,0x10);// S3C44B0X slave address

CSR_WRITE(rIICSTAT,0x10);

CSR_WRITE(rI_ISPC,(CSR_READ(rI_ISPC)|BIT_IIC));// Clear EINT'sPending Bit

CSR_WRITE(rINTMSK,(CSR_READ(rINTMSK)&(~BIT_IIC)));// Enable interrupt

ret = register_chrdev(IIC_MAJOR,"iic",&IIC_fops);

if(ret<0) {

printk("fail to register\n");

}

CLEAR_PEND_INT(IIC_IRQ);

if(IIC_IRQ >=0){

ret = request_irq(IIC_IRQ,IIC_handle,SA_INTERRUPT,"IICS",NULL);

if(ret){

printk("IIC:cant get assigned irq %i\n",IIC_IRQ);

}

else{

printk("IIC:request external interrupt %i\n",IIC_IRQ);

INT_ENABLE(IIC_IRQ);

}

}

}

void vdelay(unsigned short i)

{

ushort cm=0;

while(cm

{

cm++;

}

}

可能会用到的工具/仪表
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号