C6000 EDMA 使用心得总结

本文档详细介绍了TI C6000系列微处理器中EDMA(Enhanced Direct Memory Access)的使用经验,特别是如何实现连续不间断的数据传输。文中指出,EDMA使用两个参数表,一个由控制器维护,另一个由用户维护。对于非连续传输,只需初始化控制器维护的表;而对于连续传输,用户需初始化两个表并设置重载参数。通过示例代码,展示了EDMA的单次和连续工作模式,以及如何通过EDMA_link()函数实现通道间的链接,确保数据传输的连续性。此外,还讨论了中断处理和乒乓操作的实现细节。
摘要由CSDN通过智能技术生成

 

几天调下来,总感觉TI的文档语焉不详。不过想想也对,250页的文档是谁都要写到郁闷的。而且一个懂了的人给初学者讲东西总会自然的略过一些看似当然的关键。
     这几天遇到的问题就是EDMA可以工作,却不能连续不断的转起来。而问题的所在就在于文档没读清楚。
     文档(SPRU234,下同)在第一章的第一节的图1-2就给出了EDMA的控制块图。现在看到控制块图当然联想到实际的工作流程,但是似乎文档并没有解释EDMA的工作流程。
     在EDMA工作中,总共使用了两个参数表,其中的一个是由EDMA控制器维护的,而另一个是由用户维护的。EDMA控制器维护的参数表规则的排列在整个参数表的开始部分,一个通道一个,谁也不多谁也不少。而用户维护的参数表则被称作Reload channel parameters,随意分布在整个参数表的后半部分。现在看来,能知道EDMA控制器是用了两个参数表就可以很好的理解EDMA的工作方式。
     非连续的工作:
     EDMA可以工作在连续的和非连续的状态。数据非连续的时候可以采用单次的非连续工作状态。这时用户在初始化的时候直接初始化EDMA所维护的参数表就可以了。如下面的例子:
*edmaHandle = EDMA_open(eventId, EDMA_OPEN_RESET);
if(*edmaHandle == EDMA_HINV)
   test_exit(FAIL);

if((tcc = EDMA_intAlloc(-1)) == -1)
   test_exit(FAIL) ;

EDMA_configArgs(
   *edmaHandle,
   EDMA_OPT_RMK(
   EDMA_OPT_PRI_MEDIUM,
   EDMA_OPT_ESIZE_32BIT,
   EDMA_OPT_2DS_NO,
   EDMA_OPT_SUM_NONE,
   EDMA_OPT_2DD_YES,
   EDMA_OPT_DUM_INC,
   EDMA_OPT_TCINT_YES,
  
   EDMA_OPT_TCC_OF(tcc & 0xF),
   EDMA_OPT_TCCM_OF(((tcc & 0x30) >> 4)),
   EDMA_OPT_ATCINT_NO,
  
   EDMA_OPT_ATCC_OF(0),
   EDMA_OPT_PDTS_DISABLE,
  
   EDMA_OPT_PDTD_DISABLE,
   EDMA_OPT_LINK_NO,
   EDMA_OPT_FS_NO
   ),
   EDMA_SRC_RMK(srcAddr),
   EDMA_CNT_RMK(EDMA_CNT_FRMCNT_OF((frameCount - 1)),
   EDMA_CNT_ELECNT_OF(elementCount)),
   EDMA_DST_RMK(dstAddr),
   EDMA_IDX_RMK(EDMA_IDX_FRMIDX_OF((elementCount * 4)),
   EDMA_IDX_ELEIDX_OF(0)),
  
   EDMA_RLD_RMK(EDMA_RLD_ELERLD_OF(elementCount), EDMA_RLD_LINK_OF(0))
);
     在这里,LINK参数是被忽略的,这一点可以从TI给的例子中看到(52页开始)。相对于很多DMA控制器来说,这些参数显得很简单而TI的讲述非常详细。
     连续工作方式:
     非连续的工作方式很好理解,TI也讲得很详细,而TI在讲述连续工作方式的时候却一笔带过。和非连续的方式不同之处在于用户需要初始化两张表,而只能维护其中的一张,另一张是由EDMA控制器自动维护的。其中的EDMA维护的这张表是在EDMA工作期间使用的,而用户维护的这张表是在EDMA开始新工作的时候重载的。
     用户在初始化阶段必须先初始化EDMA通道对应的参数表,之后在参数表的后半部分申请一张空闲的参数表,并将其初始化。如文档中1.16.4.3所示的例子,其中62页示例的就是通道对应的参数表,而63页示例的就是需要重载的参数表。
     EDMA在接受了这样的参数表之后,首先判断是否达成DMA完成条件(参考TI文档),如果未完成,开始将参数表中的ELECNT自减,减到零则 FRMCNT减一,而后从ELERLD参数中重载ELECNT,在开始新的一个Frame。周而复始。当FRMCNT也减完了则从重载表重新装入参数开始新一轮的工作。用户则可以根据工作需要在EDMA控制器重载参数之前对重载参数设置以开始不同的工作。
     下面的例子是TI在例子中给出的一个三张表的例子,根据这些例子,用户甚至可以使用4张表或者更多,最多可以单一通道使用22张表(C64X)。而多通道则可以使用N+21张表。

   hEdma = EDMA_open(EDMA_CHA_TINT1, EDMA_OPEN_RESET);

   hEdmaPing = EDMA_allocTable(-1);
   hEdmaPong = EDMA_allocTable(-1);

   cfgEdma = cfgEdmaPing;
  

   cfgEdmaPing.rld = EDMA_RLD_RMK(0,hEdmaPing);
   cfgEdmaPong.rld = EDMA_RLD_RMK(0,hEdmaPong);
   cfgEdma.rld      = EDMA_RLD_RMK(0,hEdmaPong);

  
   EDMA_config(hEdma, &cfgEdma);   
   EDMA_config(hEdmaPing, &cfgEdmaPing);
   EDMA_config(hEdmaPong, &cfgEdmaPong);   
下面是Ping和Pong的参数:
EDMA_Config cfgEdmaPing = {  
   EDMA_OPT_RMK(
     EDMA_OPT_PRI_LOW,
     EDMA_OPT_ESIZE_32BIT,
     EDMA_OPT_2DS_NO,
     EDMA_OPT_SUM_NONE,
     EDMA_OPT_2DD_NO,
     EDMA_OPT_DUM_INC,
     EDMA_OPT_TCINT_YES,
     EDMA_OPT_TCC_OF(TCCINTNUM),
     EDMA_OPT_TCCM_OF(0),
     EDMA_OPT_ATCINT_NO,
     EDMA_OPT_ATCC_OF(0),
     EDMA_OPT_PDTS_DEFAULT,
     EDMA_OPT_PDTD_DEFAULT,
     EDMA_OPT_LINK_YES,
     EDMA_OPT_FS_NO
   ),
   EDMA_SRC_OF(&ping_data),
   EDMA_CNT_OF(BUFF_SZ),
   EDMA_DST_OF(ping),
   EDMA_IDX_OF(0x00000004),
   EDMA_RLD_OF(0x00000000)
};                         
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值