AutosarMcal配置开发——基于S32K3xx、EB之DMA驱动

一、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实例分别为DMAMUX0DMAMUX1

  • 在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
      在这里插入图片描述
  • **工作机制:**主要分为小循环(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搬运

  1. Mcl_Init(&Mcl_Config); //初始化DMA
  2. 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函数*/

四、测试验证

在这里插入图片描述

五、总结

本文为博主开发过程中学习总结而得,如有不正之处欢迎指正。

### S32K3 Microcontroller DMA Configuration Tutorial #### Overview of DMA on the S32K3 Series The Direct Memory Access (DMA) feature within the S32K3 series allows data transfer between memory and peripherals without CPU intervention, improving system efficiency. The eDMA module supports multiple channels with flexible arbitration mechanisms to manage concurrent requests effectively[^1]. #### Key Components Involved in DMA Setup For configuring DMA operations specifically involving ADC interfaces: - **Hardware Units**: Two hardware units can be configured as `ADC0` and `ADC1`. Users should configure these based on their specific circuit requirements[^3]. - **Channel Management**: When using multiple ADC channels, only the last channel triggers a DMA request upon completion. After one major loop finishes executing, it automatically loads the next Transfer Control Descriptor (TCD)[^2]. #### Step-by-step Guide for Configuring DMA with ADC To set up DMA transfers from an ADC peripheral: 1. Initialize the ADC modules (`ADC0`, `ADC1`) according to project needs. 2. Configure TCD settings including source address, destination address, block size, etc., ensuring proper alignment with the desired buffer structure. 3. Set up interrupt handlers if necessary to handle events such as end-of-conversion or error conditions. 4. Enable DMA requests by setting appropriate bits in control registers associated with each ADC instance used. 5. Ensure that after completing a major loop, subsequent minor loops are correctly initialized via preloaded TCD entries. ```c // Example C code snippet showing basic setup steps void init_DMA_for_ADC(void){ // Assuming initialization functions exist for simplicity /* Initialize ADC */ ADC_Init(ADC0); /* Prepare TCD structures */ edma_config_t dmaConfig; EDMA_GetDefaultConfig(&dmaConfig); EDMA_Init(DMA_BASE_ADDR, &dmaConfig); /* Create and configure TCDs */ uint8_t tcdIndex = 0; // Choose available index EDMA_CreateHandle(&g_edmaHandle[tcdIndex], DMA_BASE_ADDR, tcdIndex); } ``` This example demonstrates initializing DMA alongside ADC configurations but does not cover all possible scenarios or optimizations which may vary depending on application specifics. --related questions-- 1. How do different types of DMA modes affect performance when interfacing with ADC? 2. What considerations must be taken into account while designing buffers for storing ADC samples through DMA? 3. Can you explain how priority levels influence DMA operation among competing peripherals like UART vs SPI? 4. In what ways could interrupts play a role during continuous acquisition mode enabled by DMA?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值