S3C4510B只需要寻址HPI接口的3个寄存器,根据对这3个寄存器的寻址关系,将主机的两根地址线(ADDR2、ADDR3)分别接到DSP的(HCNTL0、HCNTL1),就可以在编程时使地址线出现要求的高、低电平,从而完成对不同寄存器的访问。我们用S3C4510B的外部I/O接口BANK1来同DSP6416相接,将外部I/O接口BANK1(地址为0x3FD4000-0x3FD8000)的片选信号nECS1接到HPI接口的片选信号HCS,这样只要对BANK1进行操作,就可以产生相应的片选信号。由于S3C4510B没有HR/W信号,所以选用ADDR4来代替该信号和HPI口的HR/W相接,只要对地址的ADDR4位为1或0的地址进行操作就可以产生高或低电平,从而选择HPI口处于写还是读状态。将S3C4510B的外部I/O接口BANK1的信号线nOE和nWBE1分别接到HPI口的HDS1和HDS2,使它们和nECS1一起通过一定的逻辑运算([NOT (nOE XOR nWBE1)] OR nECS1)组成数据闸门信号nHSTROBE(内部信号)。nHRDY为DSP就绪指示信号,由DSP产生。所有读写操作都必须在nHRDY信号有效时进行。将nHRDY信号经过反相后接到S3C4510B的nEWAIT(等待信号)上面,这样在DSP没有准备好数据的时候可以延长ARM的读写周期,使ARM处于等待DSP就绪的状态。nHINT信号是HPI口的中断信号,他既可以由DSP产生,从而中断ARM,也可以由ARM产生来中断DSP。我们将中断信号接到S3C4510B上的外部I/O口P8上,这样我们既可以由P8口产生信号中断DSP,也可以在P8口侦听来自DSP的中断信号。
5、DSP6416与S3C4510B连接的软件设计
在硬件连接设计好的基础上,我们还需要通过正确的编程才能实现我们预想的时序。因为我们在ARM S3C4510B上运行嵌入式操作系统uClinux,所以在写程序对HPI接口进行读/写操作时将HPI接口看作一个外部设备,将完成读/写操作的程序看成在uClinux下面的一个字符型驱动。这样软件的设计就变成了在uCLinux下面驱动程序的开发。考虑到S3C4510B不光要将DSP压缩编码完成的数据取过来,而且还要将这些数据传送到网络上去,这就需要这两者之间有很好的配合。
本程序的具体设计大体上可以分成两部分,一部分是对HPI接口进行读/写的程序,另外一部分属于网络编程。由于本文重点是讲解ARM CPU与DSP之间的接口问题,所以在这里介绍HPI接口读/写程序。
S3C4510B与DSP6416之间的HPI接口读/写程序主要由两个部分组成:1、ARM自身的初始化;2、HPI接口读写程序。
4.1、ARM处理器自身的初始化
ARM处理器首先要完成自身工作模式等一系列的初始化,才能正常进行HPI接口的读/写,源代码如下所示。
SYSCFG = 0xe7fffe22;
file://关掉ARM中的Cache
EXTDBWTH = 0x0ffff556;
file://使外部I/O接口BANK1工作于32位的模式
EXTACON0 = 0x08610000;
file://配置外部I/O接口BANK1的读写时序各控制线之//间的时序关系
上面这段代码主要是对几个寄存器进行配置。在配置好ARM处理器的工作模式后,对外部I/O接口BANK1的对应地址进行读/写操作,就可以完成对HPI接口的相应操作了。
4.2、HPI接口读写程序
以下这些宏定义了DSP6416的HPI接口寄存器的地址。对于本设计来说,已经将HPI口与外部I/O接口的BANK1相接,这样HPI口将占用外部I/O接口BAN1的地址。由于是使用ADDR4来模拟HPI32接口的HR/W,所以对同一个寄存器分别进行读/写操作时,在这里看来是对不同的地址进行相应的操作。
#define HPI_BASE 0x3fd4000
#define VPint *(volatile unsigned int *)
/*定义HPIC寄存器*/
#define HPICW (VPint (HPI_BASE+0x0)) 0 0 0 0 0 0 0
#define HPICR (VPint (HPI_BASE+0x40)) 0 1 0 0 0 0 0
/*定义HPIA寄存器*/
#define HPIAW (VPint (HPI_BASE+0x10)) 0 0 1 0 0 0 0
#define HPIAR (VPint (HPI_BASE+0x50)) 1 0 1 0 0 0 0
/*定义HPID寄存器*/
#define HPIDW (VPint (HPI_BASE+0x20)) 0 1 0 0 0 0 0
#define HPIDR (VPint (HPI_BASE+0x60)) 1 1 0 0 0 0 0
在定义好上面的宏以后,通过HPI驱动程序就可以将DSP中压缩编码好的视频数据通过HPI口读出来,并送到开辟的用户缓冲区中,等待取完2k大小的数据后再通过网络发送到用户端去。给出HPI驱动程序中读/写数据部分的关键源代码如下[4]:
…
for(i=0;i<hpiSize;i++)
{
HPICW=0x00000000;
file://初始化HPI口的控制寄存器
HPIAW=0x80000000;
file://初始化HPI口的地址寄存器,读DSP中地址为0x80000000的存储单元的数据
hpiBaseAddr=HPIDR;
file://通过HPI口读出2K大小的编码数据,并送到数组hpiBaseAddr[ ]中暂存
}
CpLen= hpiSize;
if(copy_to_user( buffer ,(__u8 *)(&hpi->hpiBaseAddr[j]), CpLen)) return -EFAULT;
file://将暂存在数组hpiBaseAddr[ ]中的数据拷贝到用户缓冲区进行保存。
return CpLen;
…
6、结束语
随着科技技术的不断发展,以后基于DSP芯片来执行计算密集型操作,ARM芯片来完成控制,两者配合工作的系统会得到越来越多的应用。而这两者之间能够高效、快速并且稳定的进行数据交换将是影响系统性能的关键部分之一。本文给出的S3C4510B和C6416之间的硬件连接方法和软件设计已经得到过实践的验证,是可行的和满足要求的。不同型号的ARM和DSP之间的接口设计也可以参照本文介绍的方法进行。
用户1425166 2009-4-2 11:20