TMS320F28379D——DMA

DMA

一、F28379D的DMA简介

  • 具有六个DMA通道,每个通道都有各自独立的PIE中断
  • 每个DMA通道都能够被各种外设触发源触发
  • 16-bit模式和32-bit模式(SPI为16-bit)
  • 吞吐量:传输一个word需要三个周期
  • 每个CPU都有各自的DMA控制器

二、DMA Data Path

在这里插入图片描述

三、DMA触发源的选择(寄存器手册P625)

触发的逻辑图:
在这里插入图片描述
在这里插入图片描述

Table5-1由于太长,未列完全,可翻阅寄存器手册。

四、DMA的传输方式和传输模式

在DMA传输时,一共有两个嵌套的循环,在一次DMA传输结束后,DMA传输的数据量为:(BURST_SIZE+1)*(TRANSFER_SIZE+1)

  1. Burst Loop(内循环)

    ​ BURST_SIZE寄存器可以设置每次Burst传输words的数量,一次Burst传输最大可以传输32个16-bit words,而MODE.DATASIZE能够改变DMA通道传输的是16-bit还是32bit。每次Burst传输完成后,其地址变换为:

    SRC_ADDR_ACTIVE = SRC_ADDR_ACTIVE + SRC_BURST_STEP
    DST_ADDR_ACTIVE = DST_ADDR_ACTIVE + DST_BURST_STEP

  2. Transfer Loop(外循环)

    ​ TRANSFER_SIZE寄存器可以配置Transfer传输的burst数,TRANSFER_SIZE寄存器是16-bit的寄存器,因此可以传输大量数据。每次Transfer传输完成后,其地址变化为(前提是SRC_WRAP_SIZE要大于TRANSFER_SIZE):

    SRC_ADDR_ACTIVE = SRC_ADDR_ACTIVE + SRC_TRANSFER_STEP
    DST_ADDR_ACTIVE = DST_ADDR_ACTIVE + DST_TRANSFER_STEP

OneShot Mode(默认关闭)

​ 当OneShot Mode关闭时,每次触发后只传输一次burst,在此次burst传输完成后,DMA控制器状态机直接切换到下一个优先级正在等待的DMA通道,即使本通道传输完成后又一次被触发。该模式能够防止任何通道独自占用DMA总线。

​ 当OneShot Mode打开时,每次触发后会将一个通道的所有bursts传输完成,在该模式下,很容易造成一个通道占用DMA的大部分带宽。

Continuos Mode(默认关闭)

​ 当Continuos Mode关闭时, 当DMA完成所有通道的所有bursts之后,DMA会自动关闭,如果需要再次传输,需要重新使能。

​ 当该模式打开时,会循环传输数据,不需要再次重新使能。

五、DMA的配置

​ 在该示例中,是将在RAMGS0处的数据DMA传送至在RAMGS1处。即Mem-To-Mem的传送方式。使用的是软件触发。

  1. 首先是配置DMA中断:

    EALLOW;
    PieVectTable.DMA_CH1_INT = &dma_finish_isr;
    EDIS;
    
    IER |= M_INT7;
    
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;    // Enable the PIE block
    PieCtrlRegs.PIEIER7.bit.INTx1 = 1;    //查找PIE Map映射即可知道PIE组7,第一个中断就是DMAch1中断
    EINT;
    ERTM;
    
  2. 配置DMA

    #pragma DATA_SECTION(g_ulSrcBuf0, "ramgs0");
    #pragma DATA_SECTION(g_ulDstBuf1, "ramgs1");
    #define MEM_BUFFER_SIZE 1024
    Uint32 g_ulSrcBuf0[MEM_BUFFER_SIZE];
    Uint32 g_ulDstBuf1[MEM_BUFFER_SIZE];
    
    volatile Uint32 *DMADest;
    volatile Uint32 *DMASource;
    
    void DMA_Init()
    {
        // Initialize DMA
        DMAInitialize();
    
        // Configure DMA Channel 1 (16-bit datasize)
        DMADest   = g_ulDstBuf1;                 
        DMASource = (volatile Uint32 *)g_ulSrcBuf0;
        DMACH1AddrConfig32bit(DMADest,DMASource);//配置目标地址和源地址
    
    	/***************************16-bit word 传输配置**********************************/
        //Will set up to use 16-bit datasize, pointers are based on 16-bit words
        //每次burst配置成传输32个16bit word,每个word传输完成后,源地址和目标地址都递增1
        DMACH1BurstConfig(31,1,1);     
        //每次Teransfer传输MEM_BUFFER_SIZE*2/32个burst,每次burst传输完成后源地址和目标地址递增1
        DMACH1TransferConfig((MEM_BUFFER_SIZE*2/32-1),1,1);   
        DMACH1WrapConfig(0xFFFF,0,0xFFFF,0);
    	//第一个参数是外部触发源,由于该示例是软件触发,因此为0x0,其他的选择可参考寄存器手册P625
        //其他参数定义,可参考库函数里面的介绍
        DMACH1ModeConfig(0x0,PERINT_ENABLE,ONESHOT_ENABLE,
                         CONT_DISABLE,SYNC_DISABLE,SYNC_SRC,
                         OVRFLOW_DISABLE,SIXTEEN_BIT,CHINT_END,CHINT_ENABLE);
        
        /***************************32-bit word 传输配置**********************************/
        DMACH1BurstConfig(31,2,2);     
        //每次Teransfer传输MEM_BUFFER_SIZE*2/32个burst,每次burst传输完成后源地址和目标地址递增2
        DMACH1TransferConfig((MEM_BUFFER_SIZE*2/32-1),2,2);   
        DMACH1WrapConfig(0xFFFF,0,0xFFFF,0);
    	//第一个参数是外部触发源,由于该示例是软件触发,因此为0x0,其他的选择可参考寄存器手册P625
        //其他参数定义,可参考库函数里面的介绍
        DMACH1ModeConfig(0x0,PERINT_ENABLE,ONESHOT_ENABLE,
                         CONT_DISABLE,SYNC_DISABLE,SYNC_SRC,
                         OVRFLOW_DISABLE,THIRTYTWO_BIT,CHINT_END,CHINT_ENABLE);
    }
    
  3. 在CMD文件中添加相关定义

    //在CMD的section中添加如下定义	
    ramgs0 : > RAMGS0, PAGE = 1
    ramgs1 : > RAMGS1, PAGE = 1
    
  4. 启动DMA

    //打开DMA通道1传输
    StartDMACH1();
    
    //进行软件触发
    EALLOW;
    DmaRegs.CH1.CONTROL.bit.PERINTFRC = 1;
    EDIS;
    
  5. DMA传输完成中断函数

    __interrupt void dma_finish_isr(void)
    {
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP7;
       //User Code
    }
    

注意:

  • 在定义数组时,必须要添加下面这两行

    #pragma DATA_SECTION(g_ulSrcBuf0, “ramgs0”);
    #pragma DATA_SECTION(g_ulDstBuf1, “ramgs1”);

    这是为了将g_ulSrcBuf0和g_ulDstBuf1分别定义在ramgs0和ramgs1处,不然的话,可能会将数组自动定义在其他区域,而由上面的第一张图的DMA数据传输路径可知,只有GS0-GS15RAMs和DMA总线相连,定义在其他区域,无法进行DMA传输

  • 在软件触发传输完成时,若要再次进行传输,必须再次打开DMA通道,同时再次软件触发,不然无法完成传输。

  • 在该示例中,是定义了两个uint32_t的数组,容量为1024,在传输数据为16-bit word时,如果每次burst传输的数量设置为32,则每次Transfer传输的burst次数应该设置为1024*2/32次,且地址指针都因该递增1,这样才能全部正常传输完成。但在32-bit 传输下,若想要全部传输完成,每次burst传输的数量和传输burst的次数与16-bit一样,只是地址变成递增2而已。有点迷惑,个人猜想,在手册里介绍每次burst传输的最大数据量为32*16-bit word,可能在32-bit模式下,每次burst传输的时16个32bit的数据。

  • 6
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值