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

📄 2402read-write.c

📁 read and write for eeprom
💻 C
📖 第 1 页 / 共 2 页
字号:

    //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 + -