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

📄 hpi.c

📁 ARM s3c2410与DSP5416的HPI通信程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************                      HPI Drivers                             ---------------------------------    begin                : March 10th,2008    copyright            : wangpingan    email                : wang8y8y@163.com    QQ                   : 276708824 ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   *  *                                                                         * ***************************************************************************//* this program is a driver for S3c2410 and TMS50x,which is a interface driver connecting S3c2410 and TMS54X DSP with *HPI-8, *hardware connection showed as follows: *        ARM S3c2410                           DSP  TMS5416 *         PIN                                         PIN *         DATA[0-7] <------------------------------>  HD[0-7] *         ADDR[1]   ------------------------------->  HCNTL0 *         ADDR[2]   ------------------------------->  HCNTL1 *         ADDR[3]   ------------------------------->  HBIL *         ADDR[4]   ------------------------------->  HR/W *         EINT[19]  <-------------------------------  HINT *         nCS3      ------------------------------->  HCS *         nEXT_OE   ------------------------------->  HDS1   *         nEXT_WD   ------------------------------->  HDS2 *         EXPRDY    <-------------------------------  HRDY                      * ************************************************************************ *                       SYSTEM   ADDRESS MAPPING ************************************************************************ *                              HardWare Map *--------------------------------------------------------------------------------- *                chip  select                            size&width                *    nGCS0     0X0000.0000-0X0800.0000              128MB   16/32bits *    nGCS1     0X0800.0000-0X1000.0000              128MB   8/16/32bits *    nGCS2     0X1000.0000-0X1800.0000              128MB   8/16/32bits *    nGCS3     0X1800.0000-0X2000.0000              128MB   8/16/32bits *    nGCS4     0X2000.0000-0X2800.0000              128MB   8/16/32bits *    nGCS5     0X2800.0000-0X3000.0000              128MB   8/16/32bits *    nGCS6     0X3000.0000-0X3800.0000              2/4/8/16/32/64/128MB   8/16/32bits *    nGCS7     0X3800.0000-0X4000.0000              2/4/8/16/32/64/128MB   8/16/32bits *              0x4000.0000-0x4000.0fff              Reserved *              0x4800.0000-0x6000.0000              SFR *              0x6000.0000-0xffff.ffff              Reserved            ************************************************************************* *                             SoftWare Map *---------------------------------------------------------------------------------- *           Address                                    Usage *        0x0000.0000-0x0002.0000                  Nboot *        0x0002.0000-0x000c.0000                  Eboot *        0x000c.0000-0x0200.0000                  wince Kernel   * *        0x0200.0000-0x0203.0000                  UBoot  *        0x0203.0000-0x0220.0000                  Linux Kernel *        0x0220.0000-0x0400.0000                  Linux file system * ******************************************************************************************  * * *                                    HPI Address Map * *--------------------------------------------------------------------------------------------------------------------------- *                                                         OFFSET                 USAGE *           HR/W HBIL HCNTL1 HCNTL0      (ADDR[0-3])  (ADDR[1-4]) *             1    0     0       1    b     0X09       0X12        HPI Data Register First Byte Read (MODE :continuous read) *             0    0     0       1    b     0X01       0X02        HPI Data Register First Byte Write( MODE :continuous write) *             1    1     0       1    b     0X0d       0X1a        HPI Data Register Second Byte Read (MODE :continuous read) *             0    1     0       1    b     0X05       0X0a        HPI Data Register Second Byte Write (MODE :continuous write) * * *             1    0     0       0     b    0X08       0X10        HPI Control Register First Byte Read (MODE :continuous read) *             0    0     0       0     b    0X00       0X00        HPI Control Register First Byte Write (MODE :continuous write) *             1    1     0       0     b    0X0C       0X18        HPI Control Register Second Byte Read (MODE :continuous read) *             0    1     0       0     b    0X04       0X08        HPI Control Register Second Byte Write (MODE :continuous write)  * *             0    0     1       0     b    0X02       0X04        HPI Address Register Fisrt Byte Write *             0    1     1       0     b    0X06       0X0c        HPI Address Register Second Byte Write * ***************************************************************************************************** *                                 frame protocol * ********************************************************************* *                    READ FRAME                     |      WRITE FRAME   *_____________________________________________________________________________ *    HPI ADDRESS(offset) | FUNCTION                 |      HPI ADDRESS(offset)  |FUNCTION *------------------------------------------------------------------------------------------- *    0X0001 (low)value=0x55 indicate DSP ready      |      0x0001 (low)value=0x55 indicate ARM ready *    0x0001 (high)value=0x55  indicate read frame   |      0x0001 (high) value=0x55 indicate write frame *                  effective                        |                 effective *    0x0002     read frame length  (16bit)          |      0x0002  write frame length *------------------------------------------------------------------------------------------------- *    0X0003   (low)value=0x55 dsp read interrupt    |      0x0003 (low)value=0x55 arm read interrupt *             (high)value=0x55 dsp write interrupt  |             (high)value=0x55  arm write interrupt *------------------------------------------------------------------------------------------------- *    0x0004                                         |      0x0004 *      |             read frame data                |         |        write  frame data *    0x03FF                                         |       0x03FF ***********************************************************************/#ifndef __KERNEL__   /* Kernel compile */#define __KERNEL__#endif#ifndef MODULE      /* Module compile */#define MODULE#endif//Define HPI Register Address   #define HPI_BASE          0x10000300   /* bank2 */  #define HPI_LENGTH        0x0FFF  #define HPD_READ_LOW      0x000012  #define HPD_READ_HIGH     0x00001a  #define HPD_WRITE_LOW     0x000002  #define HPD_WRITE_HIGH    0x00000a  #define HPC_READ_LOW      0x000010  #define HPC_READ_HIGH     0x000018  #define HPC_WRITE_LOW     0x000000  #define HPC_WRITE_HIGH    0x000008  #define HPA_WRITE_LOW     0x000004  #define HPA_WRITE_HIGH    0x00000c  //Define HPI major number (dynamic)  #define HPI_MAJOR         0  //Irq number  #define IRQ_NUM           IRQ_EINT3          //read buffer base adderess  #define HPI_READ_BASE_LOW     0x00  #define HPI_READ_BASE_HIGH    0x10  //write buffer base address  #define HPI_WRITE_BASE_LOW    0x00  #define HPI_WRITE_BASE_HIGH   0x14    //*******I/O Configure and interrupt cofigure*******  #define GPIO_BASE         0x56000050  #define rGPFCON           0x0000  #define rEXTINT0          0x0038  #define rEINTMASK         0x0054  #define INT_BASE          0x4A000000  #define rINTMOD           0x0004  #define rINTMSK           0x0008      //port lenghth  #define IO_SIZE           0x100  //INT lenghth  #define INT_SIZE          0x10  //Notes: include files must specify the linux source path rather than the system include path when you complile // please see the makefile#include <linux/module.h>#include <linux/config.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/kernel.h> /* printk() */#include <linux/fs.h>     /* everything... */#include <linux/errno.h>  /* error codes */#include <linux/delay.h>  /* udelay */#include <linux/slab.h>#include <linux/mm.h>#include <linux/ioport.h>#include <linux/interrupt.h>#include <linux/tqueue.h>#include <linux/poll.h>#include <asm/io.h>#include <asm/system.h>#include <linux/spinlock.h>#include <asm/irq.h>   //***************************************************** //Global varialbe definition static u32 phys_address = 0x1000; static u32 io_base_address; static u32 int_base_address; static  int         major=0; static int         read_event=0; static int         write_event=0; static spinlock_t hpi_lock=SPIN_LOCK_UNLOCKED; static unsigned long flags; DECLARE_WAIT_QUEUE_HEAD(hpi_read_queue); DECLARE_WAIT_QUEUE_HEAD(hpi_write_queue); //****************************************************       //set io portG and interrupt registervoid io_port_configure(void)     {        u32 tmp_reg;     //set GPFCON;       tmp_reg=readl(rGPFCON+io_base_address);	 udelay(5);	    printk(KERN_INFO"Read GPFCON :0x%x\n",tmp_reg);   	 writel((tmp_reg&0xffbf)|(1<<9),rGPFCON+io_base_address);	 udelay(5);	 tmp_reg=readl(rGPFCON+io_base_address);	 udelay(5);	    printk(KERN_INFO"Read Changed GPFCON :0x%x\n",tmp_reg);	   	  //set EXTINT0;	 tmp_reg=readl(rEXTINT0+io_base_address);   	    printk(KERN_INFO"Read EXTINT0 :0x%x\n",tmp_reg);	 udelay(5);	 writel((tmp_reg&0xffff8fff),rEXTINT0+io_base_address);	 udelay(5);	 tmp_reg=readl(rEXTINT0+io_base_address);	 udelay(5);	    printk(KERN_INFO"Read Changed EXTINT0 :0x%x\n",tmp_reg);  	                 /*    //set EINTMASK;	 tmp_reg=readl(rEINTMASK+io_base_address);   	    printk(KERN_INFO"Read EINTMASK :0x%x\n",tmp_reg);	 udelay(5);	 writel(tmp_reg&0xf7ffff,rEINTMASK+io_base_address);	 udelay(5);	 tmp_reg=readl(rEINTMASK+io_base_address);	 udelay(5);	    printk(KERN_INFO"Read Changed EINTMASK :0x%x\n",tmp_reg);  	   */	 //set INTMOD;	 tmp_reg=readl(rINTMOD+int_base_address);   	    printk(KERN_INFO"Read INTMOD :0x%x\n",tmp_reg);	 udelay(5);	 writel(tmp_reg&0xfffffff7,rINTMOD+int_base_address);	 udelay(5);	 tmp_reg=readl(rINTMOD+int_base_address);	 udelay(5);	    printk(KERN_INFO"Read Changed INTMOD :0x%x\n",tmp_reg);  	 //set INTMSK;	  tmp_reg=readl(rINTMSK+int_base_address);   	   printk(KERN_INFO"Read INTMSK :0x%x\n",tmp_reg);	udelay(5);   writel(tmp_reg&0xfffffff7,rINTMSK+int_base_address);	udelay(5);	tmp_reg=readl(rINTMSK+int_base_address);	udelay(5);	    printk(KERN_INFO"Read Changed INTMSK :0x%x\n",tmp_reg);  	          }             void set_arm_ready(void)     {         //set ARM ready	 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);          }         void set_arm_not_ready(void)     {      //set ARM not ready	 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(0x00,HPD_WRITE_LOW+phys_address);     }          void frame_init(void)    {         //set write frame        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);	//set arm ready        writeb(0x55,HPD_WRITE_LOW+phys_address);	//set write frame inactive	udelay(5);	writeb(0x00,HPD_WRITE_HIGH+phys_address);	udelay(5);		//set write frame length	writeb(0x00,HPD_WRITE_LOW+phys_address);	 udelay(5);	writeb(0x00,HPD_WRITE_HIGH+phys_address);		 udelay(5);	//set read & write interrupt flag 0	writeb(0x00,HPD_WRITE_LOW+phys_address);	 udelay(5);	writeb(0x00,HPD_WRITE_HIGH+phys_address);	    }		       //open file  int hpi_open(struct inode *inode,struct file *file)      {                    MOD_INC_USE_COUNT;         //set hpi control register as address auto  increase	 //clear dsp interrupt	 spin_lock_irqsave(&hpi_lock,flags);        writeb(0x09,HPC_WRITE_LOW+phys_address);           udelay(5);        writeb(0x09,HPC_WRITE_HIGH+phys_address);           udelay(5);	     	 frame_init();	 	spin_unlock_irqrestore(&hpi_lock,flags);         return 0;      /* success */      }         //close file  int hpi_release(struct inode *inode,struct file *file)     {                   //set ARM NOT ready         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(0x00,HPD_WRITE_LOW+phys_address);         MOD_DEC_USE_COUNT;         return 0;      /* success */     }       // hpi read     ssize_t hpi_read(struct file *file, char *buffer, size_t count, loff_t *pos)      {        unsigned char *kbuf ;        unsigned char dsp_ready=0;        unsigned char frame_active=0;         u16    frame_length=0;        unsigned char tempt;	int i;       		 // printk(KERN_INFO"READ :%d \n",count);      spin_lock_irqsave(&hpi_lock,flags);          writeb(0x01+HPI_READ_BASE_LOW,HPA_WRITE_LOW+phys_address);       //  udelay(5);           writeb(HPI_READ_BASE_HIGH,HPA_WRITE_HIGH+phys_address);         // udelay(5);           dsp_ready=readb(HPD_READ_LOW+phys_address);          //  udelay(5);           frame_active=readb(HPD_READ_HIGH+phys_address);       spin_unlock_irqrestore(&hpi_lock,flags);	        //   printk(KERN_INFO"dsp_ready:0x%x  frame_active:0x%x\n",dsp_ready,frame_active);                  if(dsp_ready!=0x55)             {  //DSP NOT READY                printk( "\nHPI:DSP not ready\n");                return -EINVAL;  /* Invalid argument */             }         if(frame_active!=0x55)        {   //FRAME inactive               if(file->f_flags&O_NONBLOCK)                 return 0;    /* success */                read_event=1;             while(frame_active!=0x55)                         {                       interruptible_sleep_on(&hpi_read_queue);                  if(signal_pending(current))                     return -ERESTARTSYS;		     	spin_lock_irqsave(&hpi_lock,flags);                      writeb(0x01+HPI_READ_BASE_LOW,HPA_WRITE_LOW+phys_address);             //   udelay(5);                  writeb(HPI_READ_BASE_HIGH,HPA_WRITE_HIGH+phys_address);             //   udelay(5);                 dsp_ready=readb(HPD_READ_LOW+phys_address);             //   udelay(5);		rmb();                 frame_active=readb(HPD_READ_HIGH+phys_address);	spin_unlock_irqrestore(&hpi_lock,flags);                         }                 }                     //READ FRAME LENGTH          tempt=readb(HPD_READ_LOW+phys_address);           //  udelay(5);         

⌨️ 快捷键说明

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