r9=0x00000229;/*LBUF0使能、发送、8位字宽、核时钟速率*/
dm(LCTL0)=r9;
r0=trans_data;
dm(II4)=r0;/*需要发送数据的起始地址*/
r0=1;
dm(IM4)=r0;
r0=size;
dm(C4)=r0;
ustat1=dm(LCTL0);
bit set ustat1 L0DEN;/*启动发送DMA*/
dm(LCTL0)=ustat1;
如果传输的数据不在一段连续的内存区,而是在多段数据块中,可以利用链式DMA。链式DMA可以在当前DMA操作结束后自动重新配置当前通道并开始新的DMA,所有这些操作都不需要内核的干预。在链式DMA过程中,用户只要对DMA参数配置一次,就可以方便地完成多块数据的DMA传输。
链式DMA是通过CPx寄存器实现的。对于ADSP2116X来说,CPx是一个19位的寄存器。寄存器中低18位表示相对于基地址0x40000的偏移量,用户在这个地址的内部存储器中存放下一次DMA的参数,这些参数叫做TCB(Transfer Control Blocks)。CPx中的第19位是控制当前链式DMA完成后是否产生中断的PCI位。如果把全局地址赋给CPx,则PCI位一定为1,表明一定会产生中断。
用户只需要在内存区填写多个TCB的表格,用其中的CPx字段将每个表格串起来并将第一个表格的结束地址放入CPx寄存器,就可以启动链式DMA。要终止一个链式DMA,只需要把最后一个TCB中的CPx字段填0即可。TCB结构如图1所示。

下面是建立一个链式DMA的顺序:
(1)在片内存储器中建立需要的TCB数据块;
(2)设置DMA参数寄存器,使能相应的LxDEN和LxCHEN;
(3)将第一个TCB的最后一个地址的偏移量写入CPx寄存器中,即启动了链式DMA。
链路口的数据传递可以依靠中断。链路口中断的产生有以下3种情况:
(1)DMA使能时,DMA完成后将产生一个可屏蔽中断。
(2)DMA禁止时,发送时LxBUF非满,接收时LxBUF非空。
(3)外部设备访问一个未指定的链路口,或者访问一个已指定但LBUF被禁止的链路口时,将产生一个链路服务请求(LSRQ)中断,且所有的链路口公用一个中断矢量。
前2种情况比较简单,只需要注意:ADSP2116X链路口的中断屏蔽、锁存与ADSP2106X不同,它从IRPTL/IMASK中分离出来,单独存在于寄存器LIRPTL中,并且在IMASK中加了一个链路口中断总开关LPISUMI。如果要使能某个链路口中断,则需要设置3个控制位。例如使能L0BUF中断,需要以下指令:“bit set imask LPISUMI;bit set lirptl LP0MSK;bit set mode1 IRPTEN;”。
对于上面的链路服务请求中断(LSRQ),在多SHARC通信时比较有效。通过该中断可以实现使用同一个链路口完成接收和发送数据的功能,并且在2个SHARC一个主动、另一个被动的情况下不依靠外部逻辑实现2个链路口的数据传递同步。例如SHARC-1需要通过链路口向SHARC-2传送数据,由于SHARC-1主动发送,因此只需配置好DMA参数,启动DMA即可。但是对于SHARC-2,由于被动接收,事先并不知道SHARC-1何时向自己发送数据,因此很难在适当的时候启动DMA接收。通过LSRQ中断,就可以很容易地解决这个问题。
首先将双方的链路口设置为无效。当SHARC-1需要向SHARC-2通信时(发送或接收)将自己的链路口设为有效,并根据需要从自己的链路缓冲中读写数据。由于链路通信协议规定:当发送数据时,如果对方没有响应,则将LxCLK置为高电平,数据线保持不变;当需要接收数据时,如果对方没有响应,则LxACK保持为高电平。这样,SHARC-2就会触发LSRQ中断。由于LSRQ中断的所有链路口公用一个中断矢量,因此在中断服务子程序中,首先需要判断哪个链路口有服务请求,且要区分是发送还是接收请求,然后配置相应的DMA参数,使能该链路口,从而在双方之间建立一个单向的数据通路。双方传递数据完成,会产生一个如上文中链路口中断情况(1)所示的中断。在中断服务程序中,仍然将各自的链路口设置为无效,等待下一次通信请求。下面给出一个利用LSRQ中断实现数据传递的示例。