Stellaris LM3Sxxx------DMA【3-2】

接上一章,继续更。

通道配置

μDMA控制器采用系统内存中保存一个控制表,表中包含若干个通道控制结构体。每个 μDMA通道在控制表中可
能有一个或两个结构体。控制表中的每个结构体都包含:源指针、目的指针、待传输数目、传输模式。控制表可
以定义到系统内存中的任意位置,但必须保证其连续并且按 1024 字节边界对齐。表 8-3 在 341页 列出了内存中
通道控制表的内容分布布局。每个通道在控制表中都可能包含一个或两个结构体:主控制结构体及副控制结构体。

在控制表中,所有主控制结构体的都在表的前半部分,所有副控制结构体都在表的下半部分。在较简单的传输模
式中,对传输的连续性要求不高,允许在每次传输结束后再重新配置、重新启动。这种情况一般不需要副控制结
构体,因此内存中只需放置表的前半部分,而后半部分所占用的内存可用作其它用途。如果采用更加复杂的传输
模式(例如乒乓模式或散聚模式),那就需要用到副控制结构体,此时整个控制表都必须加载到内存中。控制表
中任何未用到的内存块都可留给应用程序使用,包括任何应用程序未用的通道的控制结构体,以及各个通道中未
用到的控制字。

控制字包含以下的位域:
■ 源/目的数据宽度
■ 源/目的地址增量
■ 总线重新仲裁之前传输的数目(仲裁数目)
■ 待传输的数据单元总数
■ 采用猝发传输标志
■ 传输模式

关于控制字及其各个位域的详细介绍,请参阅“μDMA通道控制结构体”在359页。μDMA控制器在传输执行期间自
动更新待传输大小位域以及传输模式位域。当传输结束后,待传输数目将为0,传输模式将变为“已停止”。由于
控制字是由 μDMA 控制器自动修改的,因此在每次新建传输之前必须手动配置。源末指针和目的末指针不会被
自动修改,所以只要源地址或目的地址不变,就无需再进行配置。在启动传输之前,必须将DMA 通道启用置位
(DMAENASET)寄存器中的相应标志位置位,启用μDMA 通道。当需要禁用某个通道时,应将DMA通道启用清除
(DMAENACLR)寄存器中的相应标志位置位。当某个μDMA传输结束后,控制器会自动禁用该通道。

传输模式

μDMA控制器支持多种传输模式。前两种模式支持简单的单次传输。后面几种复杂的模式能够实现持续数据流。

停止模式

停止模式虽然是控制字中传输模式位域的有效值,但实际上这并不是一种真正的传输模式。当控制字中的传输模
式是停止模式时,μDMA控制器并不会对此通道进行任何传输,并且一旦该通道启用,μDMA控制器还会自动禁
用该通道。在任何μDMA传输结束后,μDMA控制器都会自动将通道控制字的传输模式位域改写为停止模式。

基本模式

在基本模式下,只要有待传输的数据单元,并且收到了传输请求,μDMA控制器便会执行传输。这种模式适用于
那些只要有数据可传输就产生μDMA请求信号的外设。如果请求是瞬时的(即使整个传输尚未完成也并不保持),
则不得采用基本模式。举例来说,如果将某个通道设为基本模式,并且采用软件启动,则启动时只会创建一个
瞬时请求;此时传输的数目等于DMA通道控制字(μDMA)(DMACHCTL)中ARBSIZE位域所指定的数目(即仲裁数
目),即使还有更多数据需要传输也将停止。
在基本模式下,当所有数据单元传输完成后,μDMA控制器自动将该通道置为停止模式。

自动模式

自动模式与基本模式类似,区别在于:每当收到一个传输请求后,传输过程会一直持续到整个传输结束,即使
μDMA请求已经消失(瞬时请求)也会持续完成。这种模式非常适用于软件触发的传输过程。一般来说外设都
不使用自动模式。在自动模式下,当所有数据单元传输完成后,μDMA 控制器自动将该通道置为停止模式。

乒乓模式

乒乓模式用于实现内存与外设之间连续不断的数据流。要使用乒乓模式,必须同时配置主数据结构体和副数据
结构体。两个结构体均用于实现存储器与外设之间的数据传输,均由处理器建立。传输过程首先从主控制结构
体开始。当主控制结构体所配置的传输过程结束后,μDMA控制器自动载入副控制结构体并按其配置继续传。
每当这时都会产生一个中断,处理器可以对刚刚结束传输过程的数据结构体进行重新配置。于是乎,主/副控制
结构体交替在缓冲区与外设之间搬运数据,周而复始,川流不息。
限于篇幅原因,具体乒乓模式工作原理可以到数据手册DMA模块查看。

聚散模式

由于此模式工作原理较复杂,在此就不讲了,本人研究的也不是很深入。聚散模式是一种很重要的工作模式。

外设接口

如果某个外设支持μDMA功能,则当其作好传输数据的准备时,将可产生一个单次请求信号及/或一个猝发请求
信号(见340页)。请求信号可通过DMA通道请求屏蔽置位(DMAREQMASKSET)启用,并通过DMA通道请求屏蔽
清零(DMAREQMASKCLR)禁用。若某个通道的请求屏蔽位置位,则禁用(屏蔽)该通道的μDMA请求信号。假如
并未屏蔽该请求信号,并且μDMA通道已经正确配置并且以及启用,则当外设产生请求信号时,μDMA控制器
将开始传输过程。

注意: 当使用μDMA与外设进行数据通信时,外设必须禁用所有到NVIC的中断。当μDMA传输结束后,μDMA控
制器产生一个中断,详见“中断及错误”在351页。关于某种外设与μDMA控制器如何相互配合工作的详细信息,
请参阅该类型外设DMA操作的相关章节。

待传输数目及增量

μDMA控制器支持传输宽度为8位、16位或32位的数据。对于任何传输,都必须保障源数据宽度与目的数据宽度
一致。源地址及目的地址可以按字节、半字或字自动递增,也可以设置为不自动递增。源地址增量及目的地址增
量相互无关,设置地址增量时只要保证其大于等于数据宽度即可。例如,当传输8位宽的数据单元时,将地址增
量设置为整字(32位)也是允许的。待传输的数据在内存中必须按照数据宽度(8位、16位或32位)对齐。
表8-5列出了从某个支持8位数据的外设进行读操作时的配置。

中断及错误

当某个μDMA传输过程结束时,μDMA控制器将在相应外设的中断向量处产生一个结束中断。因此,假如某个外设
采用μDMA传输数据,并且启用了该外设中断,那么中断处理函数中必须包含对μDMA传输结束中断的相关处理。
假如传输过程使用了软件μDMA通道,那么结束中断将在专用的软件μDMA中断向量上产生(见352页)。

当启用某外设的μDMA后,μDMA控制器将禁止该外设的普通传输中断传递到中断控制器,不过这些中断的状态仍
然能在外设的中断寄存器中查询到。因此,当采用μDMA传输大量数据时,中断控制器并不会随着数据流从外设频
繁收到中断,而是只在数据传输过程结束后收到一个中断。请注意,未屏蔽的外设错误中断仍会正常发送到中断
控制器。若μDMA控制器在尝试进行数据传输时遇到了总线错误或存储器保护错误,将会自动关闭出错的μDMA通
道,并且在μDMA错误中断向量处产生中断。处理器可以通过读取DMA总线错误清除(DMAERRCLR) 寄存器来确
定是否产生了错误中断。一旦产生错误则ERRCLR标志位将置位。向ERRCLR位写1即可清除错误状态。

表8-6列出了μDMA控制器专用的中断。

初始化及配置

模块初始化

在使用μDMA控制器之前,必须先在系统控制模块中将其启用,并且在外设中启用μDMA 功能。此外,还应当先
设置好通道控制结构体的位置。

系统初始化期间应执行一遍下面的步骤:

a) 在系统控制模块中,必须启用μDMA外设。可通过将系统控制寄存器RCGC2的UDMA置位实现(参见267页)。
b) 通过将DMA配置(DMACFG)中的MASTEREN位置位,启用μDMA控制器。
c) 向DMA通道控制基指针(DMACTLBASE)寄存器写入通道控制表的基地址。基地址必须按照1024字节对齐。

配置通道属性

首先我们应当配置通道属性:

1) 对DMA通道优先置位(DMAPRIOSET)或DMA通道优先清除(DMAPRIOCLR)寄存器的第30位编程,将通道的优先
级设置为最高优先级或者为默认优先级。
2) 将DMA通道主副清除(DMAALTCLR)寄存器中的第30位置位,为此次传输选择主通道控制结构体。
3) 将DMA通道采用猝发清除(DMAUSEBURSTCLR)寄存器中的第30位置位,以允许μDMA 控制器既能响应单次请
求也能响应猝发请求。
4) 将DMA通道请求屏蔽清零。

配置通道结构体

下面来配置通道控制结构体。

本示例需要实现的功能是:从某个内存缓冲区向另一缓冲区传输256个字。采用第30号通道进行软件启动传输,其
控制结构体在控制表中的偏移量为0x1E0。

启动传输过程

完成通道配置后,即可启动传输过程:

1) 将DMA通道启用置位(DMAENASET)寄存器中的第30位置位以启用该通道。
2) 将DMA通道软件请求(DMASWREQ)中的第30位置位,以发送传输请求。

随后就会开始μDMA传输。倘若同时开启了相关中断,那么当传输过程全部结束后还会产生中断事件通知处理器。
如果需要,还需通过读取DMAENASET寄存器中的第30位来检查状态。当传输完成后,此位自动清零。此外也可
通过通道控制字(偏移量0x1E8)的XFERMODE 位域来检查传输状态。当传输完成后,此位自动清零。

EPI + DMA 工作原理

由于EPI写操作时会发生阻塞;当单次向外设的设局超过4个字节时,就会出现阻塞情况,原因在于EPI内部WFIFO
深度为4个字,阻塞时CPU等待当前操作完成,如此便会占用CPU大量时间,为了减少CPU在EPI传输数据使用的
时间,因此使用DMA。使用DMA的好处在于:当一次写大量数据时,CPU不会发生阻塞,因为DMA后台执行,几
乎不占用CPU,而CPU可以有足够的时间处理其他任务。

DMA传输数据需要猝发条件,这个条件是由EPI产生。由数据手册知,当WFIFO的空闲单元数大于等于DMA的仲
裁数目(关于仲裁数目原理见前文)时,自动触发DMA,如果初始化并使能DMA模块,就将开始数据传输。WFIFO
中的数据在通过地址映射到片外,完成数据传输过程。例如:WFIFO空闲单元数为2个(最大4个),DMA仲裁数目
为2个,那么EPI将触发DMA,DMA向WFIFO写数据,由于WFIFO内部已经有两个数据,所以在DMA向WFIFO写
数据过程中,WFIFO的数据也会写到外设,腾出空闲单元,如果此时WFIFO空闲单元数为1,显然触发不了DMA,
于是DMA不向WFIFO写数据,直到满足触发条件。可假设为一个水池,WFIFO就是水池,DMA负责向水池注水,
外设负责放掉水池里的水。如果注入快,输出慢,就会溢出,DMA会等待,然后继续放。如果注入慢,输出快,
水池则永远装不满,当然这种情况在单片机里不太可能出现。

常见陷阱

本人由于当初对EPI不是很了解(第一次听说呀),所以走了不少弯路,在此加以说明,希望用到的朋友不会犯这种
错误。

  • 对于片外无地址设备HB8/HB16模式,DMA初始化基址应该是0xC000 0000或0xA000 0000
  • 冲裁数目最大只能为4,比较合适的值是2
  • 当使用DMA与外设进行数据通信时,必须禁用所有到NVIC的中断(血淋淋的教训啊)
  • DMA的EPI请求信号只有猝发请求信号,没有单次请求信号
  • EPI配置时,没有必要开传输中断,否则会一直进入中断
  • EPI最大数据传输速度为50M/s

代码区

void DMA_Init()
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
    SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);

    IntEnable(INT_UDMAERR); 
    uDMAEnable();
    IntEnable(INT_UDMA); 

    uDMAControlBaseSet(ucControlTable);

    uDMAChannelSelectSecondary(UDMA_DEF_TMR1B_SEC_EPI0TX );//| UDMA_DEF_TMR1A_SEC_EPI0RX

    uDMAChannelAttributeDisable(UDMA_SEC_CHANNEL_EPI0TX, UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
//    uDMAChannelAttributeDisable(UDMA_SEC_CHANNEL_EPI0RX, UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);

    uDMAChannelAttributeEnable(UDMA_SEC_CHANNEL_EPI0TX, UDMA_ATTR_USEBURST);
//    uDMAChannelAttributeEnable(UDMA_SEC_CHANNEL_EPI0RX, UDMA_ATTR_USEBURST);

    uDMAChannelControlSet(UDMA_SEC_CHANNEL_EPI0TX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_2);
//    uDMAChannelControlSet(UDMA_SEC_CHANNEL_EPI0RX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4);
}

OVER ^_^
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值