📄 2402read-write.c
字号:
//printk(">");
switch(_iicMode)
{
case POLLACK:
_iicStatus = iicSt;
break;
case RDDATA:
if((_iicDataCount--)==0)
{
//_iicData[_iicPt++] = rIICDS;
_iicData[_iicPt++] = ioread8(R_IICDS);
//rIICSTAT = 0x90; //Stop MasRx condition
iowrite8(0x90,R_IICSTAT);
//rIICCON = 0xaf; //Resumes IIC operation.
iowrite8(0xaf,R_IICCON);
//while (rIICSTAT & 0x20);
Delay(100); //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;
_iicData[_iicPt++] = ioread8(R_IICDS);
//The last data has to be read with no ack.
if((_iicDataCount)==0)
{
//rIICCON = 0x2f; //Resumes IIC operation with NOACK.
iowrite8(0x2f,R_IICCON);
}
else
{
//rIICCON = 0xaf; //Resumes IIC operation with ACK
iowrite8(0xaf,R_IICCON);
}
break;
case WRDATA:
if((_iicDataCount--)==0)
{
//rIICSTAT = 0xd0; //stop MasTx condition
iowrite8(0xd0,R_IICSTAT);
//rIICCON = 0xaf; //resumes IIC operation.
iowrite8(0xaf,R_IICCON);
//while (rIICSTAT & 0x20);
Delay(100); //wait until stop condtion is in effect.
//The pending bit will not be set after issuing stop condition.
break;
}
//rIICDS = _iicData[_iicPt++]; //_iicData[0] has dummy.
iowrite8(_iicData[_iicPt++],R_IICDS);
for(i=0;i<100;i++); //for setup time until rising edge of IICSCL
//rIICCON = 0xaf; //resumes IIC operation.
iowrite8(0xaf,R_IICCON);
break;
case SETRDADDR:
if((_iicDataCount--)==0)
{
Delay(100);
break; //IIC operation is stopped because of IICCON[4]
}
//rIICDS = _iicData[_iicPt++];
iowrite8(_iicData[_iicPt++],R_IICDS);
for(i=0;i<100;i++); //for setup time until rising edge of IICSCL
//rIICCON = 0xaf; //resumes IIC operation.
iowrite8(0xaf,R_IICCON);
break;
default:
break;
}
}
static void address_map(void)
{
R_CLKCON = (unsigned int *)ioremap(CLK_CON ,4);
R_GPECON = (unsigned int *)ioremap(IIC_GPECON,4);
R_GPEUP = (unsigned int *)ioremap(IIC_GPEUP ,4);
R_IICCON = (unsigned int *)ioremap(IIC_CON ,4);
R_IICSTAT = (unsigned int *)ioremap(IIC_STAT ,4);
R_IICADD = (unsigned int *)ioremap(IIC_ADDR ,4);
R_IICDS = (unsigned int *)ioremap(IIC_DS ,4);
/*
printk(KERN_ERR "IIC_CON=0x%x -> R_IICCON=%x \n", IIC_CON,R_IICCON);
printk(KERN_ERR "IIC_STAT=0x%x -> R_IICSTAT=%x \n", IIC_STAT,R_IICSTAT);
printk(KERN_ERR "IIC_ADDR=0x%x -> R_IICADD=%x \n", IIC_ADDR,R_IICADD);
printk(KERN_ERR "IIC_DS=0x%x -> R_IICDS0x=%x \n", IIC_DS,R_IICDS);
*/
}
static void address_unmap(void)
{
iounmap( R_CLKCON );
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,
write: IIC_write,
open: IIC_open,
release: IIC_release,
};
struct IIC_dev{
wait_queue_head_t rq; // 读取等待队列
uint8_t *buffer;
uint32_t size;
uint32_t index;
struct semaphore sem;
struct cdev cdev;
};
struct IIC_dev *my_dev;
static int __init IIC_init(void)
{
// allot major and minor
dev_t devno = MKDEV( major, minor );
int ret = register_chrdev_region( devno, 1, DEV_NAME);
if( ret < 0 )
{
printk( "register major number failed with %d\n", ret);
return ret;
}
printk( "%s:register major number OK\n",DEV_NAME);
// register dev
my_dev = kmalloc(sizeof(struct IIC_dev), GFP_KERNEL);
memset( my_dev, 0, sizeof(struct IIC_dev) );
cdev_init( &my_dev->cdev, &fops );
my_dev->cdev.ops = &fops;
my_dev->cdev.owner = THIS_MODULE;
ret = cdev_add( &my_dev->cdev, devno, 1 );
if( ret < 0 )
{
printk( "register device failed with %d\n", ret);
return ret;
}
printk( "%s:register device OK\n",DEVICE);
// Remap IIC register
address_map();
return 0;
}
static void __exit IIC_exit(void)
{
dev_t devno = MKDEV( major, minor );
// 以相反的顺序清除
address_unmap();
cdev_del( &my_dev->cdev );
kfree( my_dev );
printk(KERN_DEBUG "%s:kfree OK\n",DEVICE);
unregister_chrdev_region( devno, 1 );
printk(KERN_DEBUG "%s:unregister device OK\n",DEVICE);
}
int IIC_open(struct inode *inode, struct file *file)
{
unsigned int tmp=0;
//page read and write test
unsigned char buffer[3] = {0}, read[3] = {0};
unsigned int len,j,i;
//open iic clock
tmp = ioread32( R_CLKCON );
tmp |= 0x00010000;
iowrite32( tmp, R_CLKCON );
tmp = ioread32( R_CLKCON );
//set s3c2410 IIC
tmp = ioread32( R_GPEUP );
uiOldGPEUP=tmp; //save old value
tmp |= 0x1c000; //Pull-up disable
iowrite32( tmp, R_GPEUP );
barrier(); // 强制写入寄存器
tmp = ioread32( R_GPEUP );
tmp = ioread32( R_GPECON );
uiOldGPECON=tmp;
tmp |= 0xa0000000; //GPE15:IICSDA , GPE14:IICSCL
iowrite32( tmp, R_GPECON );
tmp = ioread32( R_GPECON );
//intk("tmp = ioread32( R_GPECON );=0x%08x\n",tmp);
//page read and write test
printk("--------->1\n");
buffer[0] = 0x0;
buffer[1] = 0x1;
buffer[2] = 0x2;
len = 3;
i=0x0;
iic_wr_page(0xa0,i,buffer,len);
for(j = 0; j<len; j++)
{
printk("The writing data is:%x\n",buffer[j]);
}
printk("--------->2\n");
iic_rd_page(0xa0,i,read,len);
for(j = 0; j<len; j++)
{
printk("The reading data is:%x \n",read[j]);
}
printk("--------->3\n");
return 0;
}
int IIC_write(struct file *file, char* buf, size_t count, loff_t *f_pos)
{
//int i=0;
U8 ucBuf[512]={0};
if( file->f_flags & O_NONBLOCK )
{
printk(KERN_ERR"if( file->f_flags & O_NONBLOCK ) err=%d\n",count);
return -EAGAIN;
}
if( count>256 )
{
printk(KERN_ERR"count err=%d\n",count);
return -EAGAIN;
}
iowrite8( 0xaf, R_IICCON );
iowrite8( 0x10, R_IICADD);
iowrite8( 0x10, R_IICSTAT );
if( copy_from_user( ucBuf, buf, count ) )
{
printk(KERN_ERR"copy_from_user err=%d\n",count);
return -EFAULT;
}
/*
//write by byte
for(i=0;i<count;i++)
{
iic_wr(0xa0,i,ucBuf[i]);
}
*/
iic_wr_page(0xa0,0,ucBuf,count);
return count;
}
int IIC_read(struct file *file, char* buf, size_t count, loff_t *f_pos)
{
//int i=0;
U8 ucBuf[512]={0};
if( file->f_flags & O_NONBLOCK )
{
return -EAGAIN;
}
if( count>256 )
{
return -EAGAIN;
}
iowrite8( 0xaf, R_IICCON );
iowrite8( 0x10, R_IICADD);
iowrite8( 0x10, R_IICSTAT );
/*
//read by byte
for( i = 0; i < count; i++ )
{
iic_rd( 0xa0, i, &ucBuf[i] );
//printk(KERN_ERR"iic_read ok and addr[0x%02x]=0x%02x\n",i,ucBuf[i]);
}
*/
iic_rd_page(0xa0,0,ucBuf,count);
if( copy_to_user( buf, ucBuf, count ) )
{
return -EFAULT;
}
//printk(KERN_ERR"read return=%d\n",count);
return count;
}
int IIC_release(struct inode *inode, struct file *file)
{
iowrite8( 0x0, R_IICCON );
iowrite8( 0x0, R_IICADD );
iowrite8( 0x0, R_IICSTAT);
barrier(); // 强制写入寄存器
iowrite32( uiOldGPECON, R_GPECON );
iowrite32( uiOldGPEUP, R_GPEUP );
return 0;
}
module_init(IIC_init);
module_exit(IIC_exit);
MODULE_AUTHOR("mikenoodle@qq.com");
MODULE_DESCRIPTION("STUDY");
MODULE_SUPPORTED_DEVICE(DEVICE);
MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -