目录
一、S32K3xx系列Dma驱动架构
Dma即直接内存访问(Direct Memory Access),DMA允许外设直接读取和写入系统内存,而无需CPU的参与来处理数据。在数据传输过程中,DMA控制器会获得总线的控制权,直接在外设和内存之间进行数据传输,从而减少了CPU的负担,提高了整体的系统效率。
1.eDMA以及DMAMUX概述
- 在S32Kxx用户手册中,DMAMUX模块负责DMA的触发管理复选功能;eDMA则负责搬运功能。
2.DMAMUX
-
下图为DMA架构图,输入为触发源信号,输出链接至对于DMA对于TCD通道
-
其中Always源在使用时总是需要软件在搬运完成后重新激活
-
S32K3XX系列拥有两个DMAMUX实例分别为DMAMUX0,DMAMUX1。
-
在S32K310 S32K311 S32K312三个MCU中DMAMUX_0中的0-5通道对应的是DMA中TCD通道0-5通道;DMAMUX_1中的6-11通道对应的是DMA中TCD通道6-15通道
-
对于其他S32Kxx设备,DMAMUX_0中的0-15通道对应的是DMA中TCD通道0-15通道;DMAMUX_1中的0-15通道对应的是DMA中TCD通道16-31通道
-
DMAMUX有三种工作模式:Disable(失能),Normal(常规),Periodic trigger(周期触发)
-
Periodic trigger(周期触发)模式:在此模式下,将会配置一个额外的定时器用于周期性触发DMA搬运,定时器为Pit(系统定时器),DMAMUX_x 0-3通道使用的对应PIT通道为PIT0 0-3通道
-
周期触发模式下有效的DMA请求为:外设请求产生并且触发器触发才会产生DMA请求
2.eDMA
- 不同设备资源支持
-
eDMA架构:分为TCD(Transfer ControlDescriptor)和eDMA引擎(BuseDMA Engine)两部分。TCD存放配置信息;eDMA引擎负责接受DMA请求并根据TCD执行对应搬运动作。
-
eDMA工作步骤:
- 触发DMA请求之后从TCD中获取源地址目标值地址搬运大小之类参数至address path模块(当然,过程中会精选通道的模式切换,优先级仲裁)
- eDMA引擎开始执行搬运操作,将会根据TCD配置信息从源地址读取对应的数据,然后写到TCD中设定的目标地址中
- 根据TCD配置的地址偏移,将原始目标源地址写回至TCD
- 触发DMA请求之后从TCD中获取源地址目标值地址搬运大小之类参数至address path模块(当然,过程中会精选通道的模式切换,优先级仲裁)
-
**工作机制:**主要分为小循环(Minor loop)与(Major loop),小循环的执行主要的搬运任务,时最小的动作单位;主循环主要用于重置配置。可根据具体项目需要设置。
-
eDMA TCD寄存器介绍:
-
寄存器启动步骤:
- 以下举例说明单次搬运配置:
TCDn_CITER = TCDn_BITER = 1 //设定major循环重载计数值
TCDn_NBYTES = 16 //需要搬运数据的总数 单位byte
/*源地址设置*/
TCDn_SADDR = 0x1000 //源地址
TCDn_SOFF = 1//每次读取源地址时指针偏移量 单位byte
TCDn_ATTR[SSIZE] = 0 //单次小循环去除的源地址字节数 0:1byte 1:2byte 2:4byte 3:8byte...
TCDn_SLAST = -16 //Marjor循环结束使用TCDn_SADDR值减去TCDn_SLAST再回写至TCDn_SADDR,所以必须为负数
/*目标地址设置*/
TCDn_DADDR = 0x2000 //与源地址类似,不再赘述
TCDn_DOFF = 4
TCDn_ATTR[DSIZE] = 2
TCDn_DLAST_SGA= –16
TCDn_CSR[INTMAJ] = 1 //开启Marjor中断
/*启动单次DMA搬运*/
TCDn_CSR[START] = 1 (should be written last after all other fields have been initialized) All
other TCDn fields = 0
之后将会按照一下步骤进行搬运
多次搬运类似,修改Marjor循环计数以及结束时回写偏移字节即可
TCDn_CITER = TCDn_BITER = 2
TCDn_SLAST = –32
TCDn_DLAST_SGA = –32
这一过程以下链接文章解释更为形象:
链接: S32K3XX单片机DMA原理深度解析
二、EB配置
1.配置介绍
- Mcl——Dma Logic Instance
硬件实例
- Mcl——Dma Logic Channel
逻辑通道,顾名思义可以链接至任意对应硬件DMA通道
2.配置示例
Adc硬件触发Dma搬运
本例展示使用DMA将配置为硬件PWM触发的Adc0的结果寄存器数据搬运至软件定义的buffer地址中
1. Adc配置触发信号至DMAMux
2. 配置对应DMA通道的DMAMUX
3. 配置Transfer(TCD)搬运参数
4. 配置Dma小循环请求Link至下一通道(通道少且集中可不配置)
5. 设定源地址以及目标地址
-
Adc配置触发信号至DMAmux,关于Adc配置不在此处详述,后续更新Adc
-
配置对应Dma通道Dmamux: 触发源选择adc0,勾选DmaRequest,不勾选DMAMUX Trigger
-
配置Transfer: Transfer里不可配置源地址与目标地址,配置好搬运参数即可,此处示例从adc0结果寄存器P通道0~7 8个通道低16位数据搬运至uint16 buffer数组中,每执行3次marjor搬运后,在buffer里重新覆盖,最终数组中呈现期望如下图
-
配置Dma小循环请求Link至下一通道: 由于S32K adc通道分为P通道S通道以及X通道,每种类型通道数量均不一致,当我们想要同时搬运跨通道的信号时则会间隔较远的地址导致空搬运,浪费资源;可以是使用DMA LINK功能,将不同的dma通道链接在一起通过主通道的小循环完成请求或者marjor循环完成请求来进行触发搬运以解决此问题,例如P通道配置一个DMA通道,S通道配置一个DMA,P通道miniloop连接至S通道DMA进行搬运
-
**设定源地址目标地址:**通过阅读S32K3 UM手册可知adc0结果寄存器地址,adc P_0通道结果寄存器地址为0x400A0100;S_0通道结果寄存器地址为0x400A0180;X_0通道结果寄存器地址为0x400A0200
uint16_t AdcChP_DmaBuffer[64ul] = {0};/*Dma buffer EB配置写入byte需与此处uint16对齐*/
Mcl_DmaChannelTransferListType TransferParaList[2u];/*传参*/
TransferParaList[0].Param = MCL_DMA_CH_SET_SOURCE_ADDRESS;/*设置源地址*/
TransferParaList[0].Value = 0x400A0100u;
TransferParaList[1].Param = MCL_DMA_CH_SET_DESTINATION_ADDRESS;/*设置目标地址*/
TransferParaList[1].Value = (uint32)(AdcChP_DmaBuffer);
Mcl_SetDmaChannelTransferList(DMA_LOGIC_CH_0,TransferParaList,2u);/*Mcal设置dma transfer函数*/
三、Mcal接口应用
1.硬件触发Adc进行DMA搬运
- Mcl_Init(&Mcl_Config); //初始化DMA
- Mcl_SetDmaChannelTransferList(…);//设定DMA transfer源地址目标地址
uint16_t AdcChP_DmaBuffer[64ul] = {0};/*Dma buffer EB配置写入byte需与此处uint16对齐*/
Mcl_DmaChannelTransferListType TransferParaList[2u];/*传参*/
Mcl_Init(&Mcl_Config);
TransferParaList[0].Param = MCL_DMA_CH_SET_SOURCE_ADDRESS;/*设置源地址*/
TransferParaList[0].Value = 0x400A0100u;
TransferParaList[1].Param = MCL_DMA_CH_SET_DESTINATION_ADDRESS;/*设置目标地址*/
TransferParaList[1].Value = (uint32)(AdcChP_DmaBuffer);
Mcl_SetDmaChannelTransferList(DMA_LOGIC_CH_0,TransferParaList,2u);/*Mcal设置dma transfer函数*/
四、测试验证
五、总结
本文为博主开发过程中学习总结而得,如有不正之处欢迎指正。