Enhanced Direct Memory Access(eDMA)

关键字 :STeDMASPC58
一、介绍

SPC58中使用的增强型直接内存访问(eDMA)控制器是第二代模块,能够在最小的主机处理器干预下执行复杂的数据传输。硬件微体系结构包括一个DMA引擎,它执行源地址和目标地址计算,以及实际的数据移动操作,以及包含64个通道中每个通道的传输控制描述符的本地内存。

图1演示了eDMA模块。

图1.eDMA框图



特征:

eDMA是一种高度可编程的数据传输引擎,可以最大限度地减少主机处理器的干预,它旨在用于要传输的数据大小是静态已知的,而不是在数据包本身中定义的应用程序。eDMA模块的特点:

  • 数据移动通过双地址传输:从源地址读取,写入到目标地址:
  • 可编程的源地址、目标地址和传输大小,加上支持增强的寻址模式。
  • 64通道实现,执行复杂的数据传输和主机处理器最小的干预。
  • 内部数据缓冲区,用作临时存储,以支持16和32字节的突发传输。
  • 连接到交叉开关总线控制数据移动。
  • 传输控制描述符(TCD)被组织为支持两层深的嵌套传输操作。
  • 每个通道的32字节TCD存储在本地内存中。
  • 由一个小字节传输计数定义的内部数据传输循坏。
  • 由一个主迭代计数定义的外部数据传输循坏。
  • 通过以下三种方法之一激活通道:
  • 显示软件初始化。
  • 通过通道对通道链接机制发起连续传输。
  • 外设节奏硬件请求(每个通道一个)。
  • 固定优先级和轮询通道仲裁。
  • 通过可选中断请求报告通道完成情况。
  • 每个通道一个中断,可选地在主迭代计数完成时使能 。
  • 每个通道的可选错误终止,并在逻辑上加在一起形成一个错误中断到中断控制器。
  • 可选支持分散 / 收集DMA处理。
  • 支持复杂的数据结构。
  • 支持通过软件取消传输。

二、操作方式

eDMA支持以下操作模式。

  1. Normal mode

在正常模式下,eDMA在源和目标之间直接传输数据。源和目标可以是内存块或能够与eDMA一起操作的I/O块。服务请求启动传输在传输控制描述符(TCD)中指定的特定字节数(NBYTES)。小循环是每个服务请求传输这些NBYTES的读写操作序列。每个服务请求执行主循环的一次迭代,该循环传输NBYTES的数据。

  1. Debug mode

DMA操作可以在调试模式下通过控制器进行配置:

  • 如果CR[EDBG]被清除,DMA继续运行。
  • 如果设置了CR[EDBG],则eDMA停止传输数据。如果在通道处于活动状态时进入调试模式,eDMA将继续运行,直到通道退出。
  1. Wait mode

在进入等待模式之前,DMA尝试完成它当前的传输。传输完成后,设备进入“等待”模式。

三、eDMA初始化

典型的eDMA初始化顺序如下:

  1. 如果不需要默认配置,则写入CR寄存器。
  2. 如果需要使用缺省配置以外的配置,则将通道优先级级别写入DCHPRIn寄存器。
  3. 如果需要,在EEI寄存器中启用错误中断。
  4. 为每个可能请求服务器的通道写入32字节的TCD。
  5. 通过ERQ寄存器启用任何硬件服务请求。
  6. 通过软件(设置TCDn_CSR[START]位)或硬件请求通道服务(从设备使能其eDMA外设请求信号)。

在任何通道请求服务之后,将根据写入程序员模型的仲裁和优先级选择执行通道。eDMA引擎将所选通道的整个TCD,包括TCD控制和状态字段(如表1所示)读入其内部地址路径模块。在读取TCD时,除非检测到配置错误,否则将内部总线上启动第一次传输。从源(由源地址TCDn_SADDR定义)到目的(由目的地址TCDn_DADDR定义)的传输一直持续到传输了指定的字节数(TCDn_NBYTES)。传输完成后,eDMA引擎的本地TCDn_SADDR、TCDn_DADDR和TCDn_CITER被写回主TCD内存,如果启用,则执行任何小环路通道链接。如果主循环耗尽,则在启用后执行进一步的后处理(中断、主循环通道链接和分散/收集操作)。

表1. TCD控制和状态字段

TCDn_CSR字段名描述
  START当使用软件发起的DMA服务时,显示启动通道的控制位(由硬件自动清除)
  ACTIVE指示通道当前正在执行的状态位
  DONE指示主回路完成的状态位(当使用软件发起的DMA服务时由软件清除)
  D_REQ当使用硬件启动的DMA服务时,在主循环完成结束时禁用DMA请求的控制位
  BWC用于通道带宽控制的节流控制位
  E_SG控制位使能散聚特性
  INT_HALF当主循环完成一半时使能中断的控制位
  INT_MAJ当主循环完成时使能中断的控制位

图2 显示了每个DMA请求如何在没有CPU干预的情况下启动一个小循环传输(迭代)。DMA仲裁可以在每个小循环之后发生,并且允许一个级别的小循环DMA抢占。主循环中的小循环的数量由开始迭代计数(BITER)指定。

图2. 多个循环迭代的示例



图3列出了内存数组术语以及TCD设置是如何相互关联的。

图3.内存数组术语



 

四、eDMA传输

Single request

要在一次激活中执行n字节数据的简单传输,请将主循环设置为1(TCDn_CITER = TCDn_BITER = 1)。在通道服务请求得到确认并选择要执行的通道后开始数据传输。传输完成后,TCDn_CSR[DONE]位被设置,如果正确启用,则会产生中断。
例如,下面的TCD表项配置为传输16字节的数据。eDMA被编程为主循环的一次迭代,每次迭代传输16字节。源内存有一个字节宽的内存端口,位于0x1000目标内存由一个32位宽的端口,位于0x2000。地址偏移量以增量方式编程以匹配传输大小:源一个字节,目标四个字节。最终的源地址和目的地址被调整为返回到它们的起始值。

TCDn_CITER = TCDn_BITER = 1
TCDn_NBYTES = 16
TCDn_SADDR = 0x1000
TCDn_SOFF = 1
TCDn_ATTR[SSIZE] = 0
TCDn_SLAST = -16
TCDn_DADDR = 0x2000
TCDn_DOFF = 4
TCDn_ATTR[DSIZE] = 2
TCDn_DLAST_SGA = -16
TCDn_CSR[INT_MAJ] = 1
TCDn_CSR[START] = 1(应该在所有其他字段初始化后最后写入)
所有其他TCDn字段= 0

这将生成以下事件序列:

  1. 用户写TCDn_CSR[START]位请求通道服务。
  2. 该通道由仲裁选择进行服务。
  3. eDMA引擎写:TCDn_CSR[DONE] = 0;TCD_CSR[START] = 0, TCDn_CSR[ACTIVE] = 1。
  4. eDMA引擎读取:通道TCD数据从本地存储器到内部寄存器文件。
  5. 源到目的的传输执行如下:
    1. 从位置0x1000读取字节,从位置0x1001读取字节,从位置0x1002读取字节,从位置0x1003读取字节。
    2. 将32位写入位置0x2000→小循环的第一次迭代。
    3. 从位置0x1004读取字节,从位置1005读取字节,从位置0x1006读取字节,从位置0x1007读取字节。
    4. 将32位写入位置0x2000→小循环的第二次迭代。
    5. 从位置0x1008读取字节,从位置0x1009读取字节,从0x100A读取字节,从0x100B读取字节。
    6. 将32位写入位置0x2008→小循环的第三次迭代。
    7. 从位置0x100C读取字节,从位置0x100D读取字节,从0x100E读取字节,从0x100F读取字节。
    8. 将32位写入位置0x200C→小循环的最后一次迭代→大循环完成。
  6. eDMA引擎写:TCDn_SADDR = 0x1000, TCDn_DADDR = 0x2000, TCDn_CITER = 1 (TCDn_BITER)。
  7. eDMA引擎写:TCDn_CSR[ACTIVE] = 0, TCDn_CSR[DONE] = 1, INT[n] = 1。
  8. 通道退出,eDMA空闲或服务下一个通道。

Multiple requests

除了通过两个硬件请求传输32字节外,下一个示例与前一个示例相同。唯一改变的字段是主循环迭代计数和最终地址偏移量。eDMA被编程为主循环的两次迭代,每次迭代传输16字节。当通道的硬件请求在ERQ寄存器中启用后,从设备发起通道服务请求。

TCDn_CITER = TCDn_BITER = 2
TCDn_SLAST = -32
TCDn_DLAST_SGA = -32

这将产生以下事件序列:

  1. 第一个硬件(eDMA外设)请求信道服务。
  2. 该通道由仲裁选择进行服务。
  3. eDMA引擎写:TCDn_CSR[DONE] = 0, TCDn_CSR[START] = 0,TCDn_CSR[ACTIVE] = 1。
  4. eDMA引擎读取:通道TCDn数据从本地存储器到内部寄存器文件。
  5. 源到目的的传输执行如下:
    1. 从位置0x1000读取字节,从位置0x1001读取字节,从0x1002,从0x1003读取字节。
    2. 将32位写入位置0x2000→小循环的第一次迭代。
    3. 从位置0x1004读取字节,从位置0x1005读取字节,从0x1005读取字节0x1006,从0x1007读取字节。
    4. 将32位写入位置0x2004→小循环的第二次迭代。
    5. 从位置0x1008读取字节,从位置0x1009读取字节,从0x100A,从0x100B读取字节。
    6. 将32位写入位置0x2008→小循环的第三次迭代。
    7. 从位置0x100C读取字节,从位置0x100D读取字节,从0x100E读取字节,从0x100F读取字节。
    8. 将32位写入位置0x200C→小循环的最后一次迭代。
  6. eDMA引擎写:TCDn_SADDR = 0x1010, TCDn_DADDR = 0x2010,TCDn_CITER = 1。
  7. eDMA引擎写:TCDn_CSR[ACTIVE] = 0。
  8. 通道退出→主循环的一次迭代。eDMA空闲或服务下一个通道。
  9. 第二硬件(eDMA外设)请求通道服务。
  10. 该通道由仲裁选择进行服务。
  11. eDMA引擎写:TCDn_CSR[DONE] = 0,TCDn_CSR[START] =0,TCDn_CSR[ACTIVE] = 1。
  12. eDMA引擎读取:通道TCD数据从本地存储器到内部寄存器文件。
  13. 源到目的的传输执行如下:
    1. 从位置0x1010读取字节,从位置0x1011读取字节,从0x1012读取字节,从0x1013读取字节。
    2. 将32位写入位置0x2010→小循环的第一次迭代。
    3. 从位置0x1014读取字节,从位置0x1015读取字节,从0x1016读取字节,从0x1017读取字节。
    4. 将32位写入位置0x2014→小循环的第二次迭代。
    5. 从位置0x1018读取字节,从位置0x1019读取字节,从0x101A读取字节,从0x101B读取字节。
    6. 将32位写入位置0x2018→小循环的第三次迭代。
    7. 从位置0x101C读取字节,从位置0x101D读取字节,从0x101E读取字节,从0x101F读取字节。
    8. 将32位写入位置0x201C→小循环的最后一次迭代→大循环完成。
  14. eDMA引擎写:TCDn_SADDR = 0x1000, TCDn_DADDR = 0x2000,TCDn_CITER = 2(TCDn_BITER)。
  15. eDMA引擎写:TCDn_CSR[ACTIVE] = 0, TCDn_CSR[DONE] = 1, INT[n] = 1。
  16. 通道退出→主循环完成。eDMA空闲或服务于下一个通道。


五、eDMA效果测试

测试SPIQ传输数据时,在不开启eDMA的情况下,如果主程序运行周期小于SPIQ传输周期,会覆盖SPIQ传输的数据,不能完全传输完整的数据串,需要为SPIQ传输增加延时,导致主程序不能按照既定的周期运行,开启eDMA后,传输数据不需要一直占用CPU资源,不影响主程序运行周期,传输完成后自动进入下一个运行周期。
SPIQ在开启eDMA时传输数据效果如下图:

图4.SPIQ开启DMA传输数据效果图

图5.SPIQ不开启DMA传输数据效果图

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论