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

📄 hpi.c

📁 ARM s3c2410与DSP5416的HPI通信程序
💻 C
📖 第 1 页 / 共 2 页
字号:
          frame_length=readb(HPD_READ_HIGH+phys_address);          frame_length=((frame_length<<8)&0xff00)|tempt;         // printk(KERN_INFO"frame length=0x%x\n",frame_length);          if(frame_length>1024)             return -EINVAL;    /* Invalid argument */               //allocate memory       	  if(count<frame_length*2)	   frame_length=count/2;             kbuf=kmalloc(frame_length*2+1,GFP_KERNEL);          if(!kbuf) return -ENOMEM;   /* Out of memory */  	  	  	          spin_lock_irqsave(&hpi_lock,flags);	 wmb();         writeb(0x04+HPI_READ_BASE_LOW,HPA_WRITE_LOW+phys_address);       // udelay(5);         wmb();         writeb(HPI_READ_BASE_HIGH,HPA_WRITE_HIGH+phys_address);       // udelay(5); 	         for(i=0;i<frame_length;i++)           {   rmb();	               *(kbuf+2*i)=readb(HPD_READ_LOW+phys_address);            	     	     	  //  udelay(5);	    rmb();          *(kbuf+2*i+1)=readb(HPD_READ_HIGH+phys_address);                           //   udelay(5);		              }	spin_unlock_irqrestore(&hpi_lock,flags);           copy_to_user(buffer,kbuf,frame_length*2);	spin_lock_irqsave(&hpi_lock,flags);                  //RESET FRME INACTIVE	 wmb();        writeb(0x00+HPI_READ_BASE_LOW,HPA_WRITE_LOW+phys_address);       // udelay(5);	wmb();        writeb(0x00+HPI_READ_BASE_HIGH,HPA_WRITE_HIGH+phys_address);       // udelay(5);	writeb(dsp_ready,HPD_WRITE_LOW+phys_address);	//udelay(5);	rmb();        writeb(0x00,HPD_WRITE_HIGH+phys_address);        //set arm read interrupt flag	//udelay(5);	wmb();        writeb(0x02+HPI_WRITE_BASE_LOW,HPA_WRITE_LOW+phys_address);       //  udelay(5);        writeb(0x00+HPI_WRITE_BASE_HIGH,HPA_WRITE_HIGH+phys_address);	//udelay(5);	wmb();        writeb(0x55,HPD_WRITE_LOW+phys_address);	//udelay(5);        writeb(0x00,HPD_WRITE_HIGH+phys_address);                //trigger dspint interrupt         writeb(0x0d,HPC_WRITE_LOW+phys_address);       //   udelay(5);         writeb(0x0d,HPC_WRITE_HIGH+phys_address);       //   udelay(5);	spin_unlock_irqrestore(&hpi_lock,flags);                  //Free Memory         kfree(kbuf);         read_event=0;         return frame_length*2;     /* success */              } //hpi write    ssize_t hpi_write(struct file *file,const char *buffer,size_t count ,loff_t *ppos)      {         unsigned char *kbuf ;         unsigned char dsp_ready=0;         unsigned char frame_active=0x55;         size_t    frame_length=0;         unsigned char tempt;	 int       i;         frame_length=count+1;       printk(KERN_INFO "COUNT=0X%x\n" ,count);	//read dsp ready flag;	spin_lock_irqsave(&hpi_lock,flags);	writeb(0x01+HPI_READ_BASE_LOW,HPA_WRITE_LOW+phys_address);	//udelay(5);	writeb(0x00+HPI_READ_BASE_HIGH,HPA_WRITE_HIGH+phys_address);	//udelay(5);	dsp_ready=readb(HPD_READ_LOW+phys_address);	//udelay(5); 	//READ if data have been taken	wmb();        writeb(0x01+HPI_WRITE_BASE_LOW,HPA_WRITE_LOW+phys_address);      //  udelay(5);        writeb(0x00+HPI_WRITE_BASE_HIGH,HPA_WRITE_HIGH+phys_address);       // udelay(5);            readb(HPD_WRITE_LOW+phys_address);      //  udelay(5);        frame_active=readb(HPD_WRITE_HIGH+phys_address);        spin_unlock_irqrestore(&hpi_lock,flags);         if(dsp_ready!=0x55)             {  //DSP NOT READY                printk(KERN_INFO "HPI:DSP not ready");                return -EINVAL;             }             //If frame has not been read or reading ,loop           if(frame_active==0x55)                 {   //FRAME inactive                if(file->f_flags&O_NONBLOCK)		 {printk(KERN_INFO "Write Frame inactive\n");                  return 0;    /* success */		 }                 write_event=1;              while(frame_active==0x55)                 {                      interruptible_sleep_on(&hpi_write_queue);                   if(signal_pending(current))                      return -ERESTARTSYS;	     spin_lock_irqsave(&hpi_lock,flags);	      		//   udelay(5); 		   wmb();                     writeb(0x01+HPI_WRITE_BASE_LOW,HPA_WRITE_LOW+phys_address);               //    udelay(5);                   writeb(0x00+HPI_WRITE_BASE_HIGH,HPA_WRITE_HIGH+phys_address);               //     udelay(5);		    rmb();		   frame_active=readb(HPD_READ_HIGH+phys_address);                    spin_unlock_irqrestore(&hpi_lock,flags);		                     }            }             if(count>2048)             return -EINVAL;             //allocate memory          kbuf=kmalloc(frame_length,GFP_KERNEL);          if(!kbuf) return -ENOMEM;          copy_from_user(kbuf,buffer,count);                     //write data into frame	  spin_lock_irqsave(&hpi_lock,flags); 	            writeb(0x03+HPI_WRITE_BASE_LOW,HPA_WRITE_LOW+phys_address);	  udelay(5);          writeb(0x00+HPI_WRITE_BASE_HIGH,HPA_WRITE_HIGH+phys_address);          for( i=0;i<count/2;i++)             {//  udelay(5);  	       wmb();               writeb(*(kbuf++),HPD_WRITE_LOW+phys_address);              // udelay(5);	       writeb(*(kbuf++),HPD_WRITE_HIGH+phys_address);              }         //  udelay(5);                //set write frame active          writeb(0x00+HPI_WRITE_BASE_LOW,HPA_WRITE_LOW+phys_address);	             // udelay(5);	  writeb(0x00+HPI_WRITE_BASE_HIGH,HPA_WRITE_HIGH+phys_address);	   //  udelay(5);          writeb(0x55,HPD_WRITE_LOW+phys_address);               // udelay(5);          writeb(0x55,HPD_WRITE_HIGH+phys_address);                //calculate frame length          tempt=(unsigned char)(count&0xff);	 //  udelay(5);          writeb(tempt,HPD_WRITE_LOW+phys_address);          tempt=(unsigned char )((count>>8)&0xff);         //  udelay(5);	  writeb(tempt,HPD_WRITE_HIGH+phys_address);           //set write interrupt flag	 //   udelay(5);        writeb(0x00,HPD_WRITE_LOW+phys_address);       //  udelay(5);	writeb(0x55,HPD_WRITE_HIGH+phys_address);         //trigger dspint interrupt         writeb(0x0d,HPC_WRITE_LOW+phys_address);        // udelay(5);               writeb(0x0d,HPC_WRITE_HIGH+phys_address);       spin_unlock_irqrestore(&hpi_lock,flags);                  //free memory          kfree(kbuf);            write_event=0;        return count;        /* success */            }   unsigned int hpi_poll(struct file *file, poll_table *wait)     {       poll_wait(file,&hpi_read_queue,wait);       poll_wait(file,&hpi_write_queue,wait);       if(read_event==0)          if(write_event==0)             return POLLIN|POLLRDNORM|POLLOUT|POLLWRNORM;   /* read and write */          else            return POLLIN|POLLRDNORM;                       /* read */       else           if(write_event==0)            return POLLOUT|POLLWRNORM;                      /* write */                           return  0;     }                                                                                                                                                                                                    static void hpi_interrupt(int irq ,void *dev_id, struct pt_regs *regs)        {          unsigned char read_flag,write_flag;	 // clear interrrupt;    writel(0xffffffff,rINTMSK+int_base_address);	 	  	// udelay(5);          writeb(0x03+HPI_READ_BASE_LOW,HPA_WRITE_LOW+phys_address);	// udelay(5);         writeb(0x00+HPI_READ_BASE_HIGH,HPA_WRITE_HIGH+phys_address);	// udelay(5);	          read_flag=readb(HPD_READ_LOW+phys_address);	// udelay(5);         write_flag=readb(HPD_READ_HIGH+phys_address);         if(read_flag==0x55)            wake_up_interruptible(&hpi_write_queue);         if(write_flag==0x55)            wake_up_interruptible(&hpi_read_queue);	               writeb(0x09,HPC_WRITE_LOW+phys_address);	//   udelay(5);           writeb(0x09,HPC_WRITE_HIGH+phys_address);   // resume interrupt	   writel(0xfffffff7,rINTMSK+int_base_address); 	  return ;        }         	     //file struction struct file_operations hpi_fops={        owner:THIS_MODULE,        read: hpi_read,        write: hpi_write,        poll : hpi_poll,        open: hpi_open,        release: hpi_release,       };                                                   /*module init   *  */  int hpi_init(void)   {                int result;      phys_address=HPI_BASE;      //allocate i/o and interrupt region      printk(KERN_INFO"\n\n\n");      printk(KERN_INFO"******************************************************************\n");      printk(KERN_INFO"           Welcome to use our system!!\n");      printk(KERN_INFO"This HPI driver is used for connecting ARM:S3c2410 and DSP:TMS54x \n");      printk(KERN_INFO"        Written by wangpingan HuNan Normal University !\n");      printk(KERN_INFO"               Email:wang8y8y@163.com \n");      printk(KERN_INFO"******************************************************************\n");                  if(! (io_base_address=(u32)ioremap(GPIO_BASE,IO_SIZE)))        { 	  printk(KERN_INFO"HPI:can't get GPIOG setting configure register address:0x%lx\n",(long unsigned int)GPIO_BASE);	     return -EIO;    /* I/O error */	}	 printk(KERN_INFO"GPIOG register Mapped io memory :0x%lx\n",(long unsigned int)io_base_address);	  if(! (int_base_address=(u32)ioremap(INT_BASE,INT_SIZE)))        { 	  printk(KERN_INFO"HPI:can't get interrupt setting configure register address:0x%lx\n",(long unsigned int)INT_BASE);	     return -EIO;	}	 printk(KERN_INFO"interrupt register Mapped io memory :0x%lx\n",(long unsigned int)int_base_address);		  io_port_configure();	             //allocate memory i/o	 if(! (phys_address=(u32)ioremap(HPI_BASE,HPI_LENGTH)))       {	  printk(KERN_INFO"HPI:can't get HPI setting I/O port address:0x%lx\n",(long unsigned int)HPI_BASE);	     return -EIO;    /* I/O error */	}	  printk("HPI:HPI setting I/O port Mapped io memory:0x%lx\n",(long unsigned int)phys_address);  	      if(NULL==request_region((long unsigned int)phys_address,HPI_LENGTH,"HPI"))         {         printk(KERN_INFO"HPI:HPI request_region failed!\n");	          return -EIO;   /* Failure */        }         printk(KERN_INFO"HPI:HPI request_region success!\n");          //Register device      result=register_chrdev(HPI_MAJOR,"HPI",&hpi_fops);      if(result<0)          {           printk(KERN_INFO "HPI:can't get major number \n");                    	    release_region((long unsigned int)phys_address,HPI_LENGTH);       iounmap ((void *)phys_address);	    iounmap ((void *)io_base_address);       iounmap ((void *)int_base_address);                    return result;   /* Failure */           }          major=result;     printk(KERN_INFO "HPI: get major number is:%d\n",(unsigned int )result);                               //set lowlevle trigger         set_external_irq(IRQ_NUM,EXT_LOWLEVEL,GPIO_PULLUP_DIS);         //requset irq         result=request_irq(IRQ_NUM,hpi_interrupt,SA_INTERRUPT,"HPI",NULL);         if(result)             {             printk(KERN_INFO "HPI:can't get assigned irq\n");	   	    release_region((long unsigned int)phys_address,HPI_LENGTH);       iounmap ((void *)phys_address);	    iounmap ((void *)io_base_address);       iounmap ((void *)int_base_address);                                      return -EBUSY;   /* Device or resource busy */             }          else             {  	       printk(KERN_INFO"Irq application ok !!!!\n");	       	       	       //clear dsp interrupt           //while(1)	       writeb(0x09,HPC_WRITE_LOW+phys_address);             	        udelay(5);			       writeb(0x09,HPC_WRITE_HIGH+phys_address);	        udelay(5);				set_arm_ready();	                     }                        return 0;              }  //unload modlue  void hpi_cleanup(void)   {      writel(0xffffff,rEINTMASK+io_base_address);      udelay(2);            set_arm_not_ready();      //free irq     free_irq(IRQ_NUM,NULL);         //unregister device	     unregister_chrdev(major,"HPI");         release_region((long unsigned int)phys_address,HPI_LENGTH);     iounmap ((void *)phys_address);     iounmap ((void *)io_base_address);     iounmap ((void *)int_base_address);        printk(KERN_INFO"HPI:successfully unload ! See you!\n");   }      module_init(hpi_init);   module_exit(hpi_cleanup);                              

⌨️ 快捷键说明

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