DSP

TS101的链式DMA操作方法

2019-07-13 16:50发布

 最近在用TS101进行采集图像数据,需要将FPGA内建的双口RAM里的数据通过FLYBY的方式读到SDRAM里。这就要用到DMA了。
       FLYBY这个东西是个好东西,可以通过DSP的总线在两个外设之间互传东西,而且不用占用DSP周期。但是DMA有一点点让人郁闷,就是只能用一次。不像从前用51的时候里面的那个定时器还有一个自动重装的模式,完全不用你管,每次计数满之后再装入初值。用TS101解决这个问题需要用到链式DMA。这个链式DMA比51里面的自动重装功能强大很多,但是却又麻烦很多,以至于我研究了差不多一天才研究出来怎么用。不过如果我英语好一点的话可能会快一点,一方面因为网上基本上没有人写这方面的文章,另一方面ADI是美国的公司,他不可能用中文写芯片资料。
       好,废话不多说了,下面开始介绍方法。
       要看这篇文章,要求您首先对TS101中DMA的TCB(传输控制块)寄存器有一定的了解。什么叫一定呢?就是你要知道每一位是做什么用的。如果在这篇文章里去介绍TCB的每一位是什么的话,那我还不如翻译一下ADI的datasheet。
       下面先介绍一下链式DMA的工作过程:当DSP完成一次DMA传输时,TCB寄存器不会复原,所以,如果你不管的话,你只能进行一次DMA。而如果你使能了链式DMA的话(TCB_DP_22),这一次DMA传输完后就会从链指针寄存器(TCB_DP_0~14)所指向的地址里把下一个存有TCB配置参数的寄存器里把TCB读出来,并写到链目的通道(TCB_DP_17~21)上。基中还会遇到一个问题,就是选择链指针寄存器所指向的地址是哪一个存储器块里面的。这通过TCB_DP_15~16进行设置。那我哪知道程序把它存到哪里了?我等下再说限制的办法,这个办法可以做到你让一个变量存到哪个块的哪个地方,他就存到哪个块的哪个地方。
       在做任何一件事时,无论是硬件还是软件,都要做一个需求分析。比如说,你要邮一封信,就要写清对方的地址,还要写清你的地址,再选择一个邮寄方式。缺少了任意一个都是不好的。好,那我们不邮信了,改成操作链式DMA了。就要知道,链式DMA的TCB_DP_0~14指向的是内存中的哪个地址、在哪一个块里。光取出东西够不够?不够,还要知道这个链要指向哪里,就是我把这个地址里的数据送到哪里去呢?这就要设置一下TCB_DP_17~21了。只有把这些都设完,头脑中才会出现一个完整的画面。其实,这些东西都是以一个最简单的方式存在的,你所要做的就是让程序知道你想要从哪里去哪里怎样去。
       一开始,我对TCB_DP_0~14怎么设不知道,不知道这个地址怎么得到。后来知道了,在VDSP里,可以通过编辑LDF文件来实现对一变量存储位置的约束。具体的方法如下:
       利用ulteredit或其它编译工具打开工程里面的LDF文件,找到MEMORY{…(表示里面有好多东西)},在里面加入一行:
TCB_DATA       { TYPE(  RAM) START(0x100000) END(0x100007) WIDTH(32)  }
START(0x100000) END(0x100007)表示我的起始地址是在0x100000,这就是MEMORY BLOCK2。注意你这里用了一段地址,就要在前面重复的地方把这个地址减去,要不就重复了。如原来的:
M2Data      { TYPE(  RAM) START(0x00100000) END(0x0010ffff) WIDTH(32)     }
       就被我改成了后来这个样子:
M2Data      { TYPE(  RAM) START(0x00100008) END(0x0010ffff) WIDTH(32)     }
       这样说大家就明白了吧。
       然后还要在SECTIONS{…}里加上这样几行:
        TCB_DATA{
        INPUT_SECTION_ALIGN(4)
                            INPUT_SECTIONS($OBJECTS(TCB_DATA))
        }>TCB_DATA
       然后呢,在程序里你就可以这样声明你的变量:
section("TCB_DATA") TCB TCB_Send,TCB_Rev;      //TCB是我定义的一个结构体,装载TCB寄存器里的东东。
这样,我所定义的TCB_Send在运行时就会一直在0x00100000,而TCB_Rev就在0x00100004喽。而他们所处的块就在块2喽。这下,你就知道TCB_DP_0~14怎样去设置了吧?
然后呢?然后当每次DMA传输完后,就会找到相应的地址里重新把TCB读出来,然后给谁呢?这就需要设置TCB_DP_17~21,哪个数代表什么芯片资料里面都会有写的。
如果大家对我说的没有看懂(确实写得不好,混乱),就去ADI的网站上下一个:
VisualDSP++ 4.5 C Compiler and Library Manual for TigerSHARC Processors (Revision 3.0, April 2006) .pdf
这个文件,里面的2-25页就也有写操作方法。这才是官方的方法噢,我是山寨的他的。
这个东西的确有点绕人,大家多想一想应该就想清楚啦。