16 uboot study DMA控制器介绍

2016-09-29  本文已影响264人  2625K

DMA 简介

DMA (Direct Memory Access ,直接内存存取)是比一种效率比较高的系统内部的一种数据传输方式,在系统运行时经常需要从一个地址空间拷贝大量数据到另一个地址空间,每次拷贝都需要占用cpu大量的时间,不能够去执行其他的工作,而DMA控制器就是为了解决这个问题,当需要拷贝数据时,cpu只要告诉DMA控制器源地址,目标地址,拷贝大小这些参数后就可以去做其他事情了,DMA会接管相关总线,去完成数据拷贝的工作。当DMA完成传输工作后,会通知CPU来进行处理。这样就大大提高了CPU的工作效率。

S3C6410的DMAC

S3C6410 包括4个DMA控制器,每个DMA控制器有8个传输通道,DMA控制器的每个通道都能够无限制的在AXI SYSTEM 总线和AXI PERIPHERAL 总线之间通过AHBtoAXI 桥路传输数据。换句话说,每个通道能够应用在下面的场合:

DMA的主要优势就是在没有CPU的干涉下也能进行数据传输,DMA传输操作可以被软件或硬件驱动,或者是内部外设的请求,或者是外部引脚的请求。
一些特性:

blockblock

S3C6410 支持64个DMA 源,四个DMA控制器分为安全DMA控制器和通用DMA控制器两种,通过系统控制模块中的SDMA_SEL寄存器进行选择,64个DMA源如下表:


sourcesource

使能一个DMA通道的步骤

寄存器描述

四个DMA控制器被命名为DMAC0,DMAC1,SDMAC0,SDMAC1,寄存器基地址分别为0x7500_0000,0x7510_0000,0x7DB0_0000和0x7DC0_0000。


regreg
regreg
regreg

简单代码分析

/*
S3C6410中DMA操作步骤:
1、决定使用安全DMAC(SDMAC)还是通用DMAC(DMAC);
2、开启DMAC控制,设置DMAC_Configuration寄存器;
3、清除传输结束中断寄存器和错误中断寄存器;
4、选择合适的优先级通道;
5、设置通道的源数据地址和目的数据地址(设置DMACC_SrcAddr和DMACC_DestAddr);
6、设置通道控制寄存器0(设置DMACC_Control0);
7、设置通道控制寄存器1,(传输大小,设置DMACC_Control1);
8、设置通道配置寄存器;(设置DMACC_Configuration)
9、使能相应通道(设置DMACC_Configuratoin);
*/

#define SDMA_SEL                (*((volatile unsigned long *)0x7E00F110))
#define DMACIntTCClear          (*((volatile unsigned long *)0x7DB00008))
#define DMACIntErrClr           (*((volatile unsigned long *)0x7DB00010))
#define DMACConfiguration       (*((volatile unsigned long *)0x7DB00030))
#define DMACSync                (*((volatile unsigned long *)0x7DB00034))
#define DMACC0SrcAddr           (*((volatile unsigned long *)0x7DB00100))
#define DMACC0DestAddr          (*((volatile unsigned long *)0x7DB00104))
#define DMACC0Control0          (*((volatile unsigned long *)0x7DB0010c))
#define DMACC0Control1          (*((volatile unsigned long *)0x7DB00110))
#define DMACC0Configuration     (*((volatile unsigned long *)0x7DB00114))


#define UTXH0           (volatile unsigned long *)0x7F005020

char src[100] = "\n\rHello World-> This is a test!\n\r";


void dma_init()

{

    //DMA控制器的选择(SDMAC0)
    SDMA_SEL = 0;


    /* 如果外设的工作时钟与DMA控制器的时钟不相同, 要使能"同步逻辑" */
    DMACSync = 0;

    //DMA控制器使能
    DMACConfiguration = 1;


    //初始化源地址
    DMACC0SrcAddr = (unsigned int)src;
    

    //初始化目的地址
    DMACC0DestAddr = (unsigned int)UTXH0;

    //对控制寄存器进行配置
    /*
    源地址自增
    目的地址固定、
    目标主机选择AHB主机2
    源主机选择AHB主机1
    */


    DMACC0Control0 =(1<<25) | (1 << 26)| (1<<31);
    DMACC0Control1 = 0x64;     //传输的大小
    /*
    流控制和传输类型:MTP 为 001
    目标外设:DMA_UART0_1,源外设:DMA_MEM
    通道有效: 1
    */
    DMACC0Configuration = (1<<6) | (1<<11) | (1<<14) | (1<<15);
}

void dma_start()
{
    //开启channel0 DMA
    DMACC0Configuration  = 1;
}
上一篇 下一篇

猜你喜欢

热点阅读