• ok6410的DMA裸机总结


    1.为何使用DMA:为了提高CPU的工作效率,避免多余的等待时间


    2.关于DMA控制器:
    (1)通道数:2440有4个通道,6410有4个DMA控制器(初始化的时候要选择),32个通道。210有两种DMA一种是内存与内存之间,另外则是普通的内存与外设之间。
    (2)请求源:
    (3)基本时序
      nXDREQ请求生效并经过2CLK周期同步后,nXDACK响应并开始生效,但至少还要经过3CLK的周期延迟,DMA控制器才可获得总线的控制权,并开始数据传输
    (4)工作模式:
    •Demond模式:
    如果DMA完成一次请求后如果Request仍然有效,那么DMA就认为这是下一次DMA请求,并立即开始下一次的传输

    •Handshake模式:
    DMA完成一次请求后等待Request信号无效,如果Request无效,DMA会无效ACK两个时钟周期,再等待下一次Request。

    3.初始化
    (1)源地址寄存器初始化(总线模式以及地址是否增加,还有选择通道,指定地址)
    (2)目的地址寄存器初始化
    (3)控制寄存器初始化(选择DMA请求源,选择源是软件还是硬件,是否重加载以及计数值决定发送多少数据)

    范例代码:

    /*
    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] = "
    
    Hello World-> This is a test!
    
    ";
    
    
    void dma_init()
    {
        //DMA控制器的选择(SDMAC0)
        SDMA_SEL = 0;
        
        //DMA控制器使能
        DMACConfiguration = 1;
        
        
        //初始化源地址
        DMACC0SrcAddr = (unsigned int)src;
        
        
        //初始化目的地址
        DMACC0DestAddr = (unsigned int)UTXH0;
    
        //对控制寄存器进行配置
        /*
        源地址自增
        目的地址固定、
        目标主机选择AHB主机2
        源主机选择AHB主机1
        */
    
        DMACC0Control0 =(1<<25) | (1 << 26)| (1<<31);  /* 25选择目的地址 26源地址增长  31中断允许位  */
        DMACC0Control1 = 0x64;     //传输的大小
        
        
        
        /*
        流控制和传输类型:MTP 为 001
        目标外设:DMA_UART0_1,源外设:DMA_MEM
        通道有效: 1
        */
    
        DMACC0Configuration = (1<<6) | (1<<11) | (1<<14) | (1<<15); /* 6选择目的地址是否为外设   11流控位 memory to peripheral 14and15 中断屏蔽 */
    
                    
    }
    
    void dma_start()
    {
        //开启channel0 DMA
        DMACC0Configuration  = 1;    
    }
  • 相关阅读:
    网络编程学习小结
    我的学习笔记_Windows_HOOK编程 2009-12-03 11:19
    void及void指针含义的深刻解析
    Android开发之自己定义TabHost文字及背景(源码分享)
    ActionBar自己定义改动无效解决方法
    一位Erlang程序猿的自白
    Xcode 5.1安装插件:规范凝视生成器VVDocumenter
    Socket程序中的Error#10054错误
    CSDN博客清理缓存
    ACM 位运算
  • 原文地址:https://www.cnblogs.com/chd-zhangbo/p/5296277.html
Copyright © 2020-2023  润新知