S3C2440 DMA工作原理

发布者:SunshineHope最新更新时间:2022-05-29 来源: eefocus关键字:S3C2440  DMA  工作原理 手机看文章 扫描二维码
随时随地手机看文章

这里具体DMA CONTROL寄存器(DCON)的配置说明,进而引出DMA的各种工作方式。


Atomic transfer:指的是DMA的单次原子操作,它可以是Unit模式(传输1个data size),也可以是burst模式(传输4个data size),具体对应DCON[28]。


Data Size:指的是单次原子操作的数据位宽,8、16、32,具体对应DCON[21:20]。

Request Source:DMA请求的来源有两种,软件&硬件模块,由DCON[23]控制;当为前者时,由软件对DMASKTRIG寄存器的位0置位触发一次DMA 操作。当为后者时,具体来源由DCON[26:24]控制,不同硬件模块的某时间触发一次DMA操作,具体要见不同的硬件模块。
   
DMA service mode:DMA的工作模式有两种,单一服务模式&整体服务模式。前一模式下,一次DMA请求完成一项原子操作,并且transfer count的值减1。后一模式下,一次DMA请求完成一批原子操作,直到transfer count等于0表示完成一次整体服务。具体对应DCON[27]。


RELOAD:在reload模式下,当transfer count的值变为零时,将自动加src、dst、TC的值加载到CURR_DST、 CURR_SRC、CURR_TC,并开始一次新的DMA传输。该模式一般和整体服务模式一起使用,也就是说当一次整体服务开始后,src、dst、TC 的值都已经被加载,因此可以更改为下一次服务的地址,2410说明文档中建议加入以下语句来判断当前的服务开始,src、dst、TC的值可以被更改了:while((rDSTATn & 0xfffff) == 0) ;

Req&Ack:DMA请求和应答的协议有两种,Demard mode 和 Handshake mode。两者对Request和Ack的时序定义有所不同:在Demard模式下,如果DMA完成一次请求如果Request仍然有效,那么DMA就认为这是下一次DMA请求;在Handshake模式下,DMA完成一次请求后等待Request信号无效,然后把ACK也置无效,再等待下一次Request。这个设计外部DMA请求时可能要用到。


传输总长度:DMA一次整体服务传输的总长度为:

Data Size × Atomic transfer size × TC(字节)。

  
2410的DMA支持四类DMA传输:系统总线到系统总线(ASB/AHB to ASB/AHB),系统总线到外设总线(ASB/AHB to APB),外设总线到系统总线(APB to ASB/AHB),外设总线到外设总线(APB to APB)。


2410 DMA 的服务模式:
共有两种服务模式,一种是单一服务模式(single service),另外一种是整体服务模式(whole service)。


在单一服务模式下,不使用传统的DMA计数器,三个DMA状态被顺序执行一次后停止,等待DMA 请求再一次来临后再重新开始另一次循环。


在整体服务模式下,使用传统的DMA 计数器,状态机会停留在状态三,直到DMA计数器的值减为零,再回到状态一,等待下一次DMA请求。


2410 DMA 数据传输模式:
共有两种数据传输模式:
单位数据传输模式:执行一次读操作和一次写操作。
并发数据传输模式:执行四次读操作和四次写操作。


2410 DMA 的基本时序:
nXDREQ请求生效并经过2CLK周期同步后,nXDACK响应并开始生效,但至少还要经过3CLK的周期延迟,DMA控制器才可获得总线的控制权,并开始数据传输。


2410 DMA 的两种协议模式:
请求模式:If XnXDREQ remains asserted, the next transfer starts immediately. Otherwise it waits for XnXDREQ to be asserted.
握手模式:If XnXDREQ is deasserted, DMA deasserts XnXDACK in 2cycles. Otherwise it waits until XnXDREQ is deasserted.


2410 DMA REQ与ACK 协议类型:
共有三种协议类型:
单一服务请求:

单一服务握手:


整体服务握手:


根据上面所说的服务模式和协议模式,很容易推知这三种协议的时序分别是什么。

//=================================================

以下分配了四个DMA通道:

s3c2410_dma_t dma_chan[MAX_S3C2410_DMA_CHANNELS];

每个DMA通道维护着一个多缓冲区组成的单链表等待队列,执行DMA操作时先更新DMA通道控制寄存器内容,再依次摘取当前缓冲区投入使用,缓冲区头指针顺次前移;需要插入新的缓冲区时,可从head或tail插入;

图A详细分析了数据结构关系:

 

DMA驱动主要函数功能分析(linux/arch/arm/mach-s3c2410/dma.c) 
写一个DMA驱动的主要工作包括:DMA通道申请、DMA中断申请、控制寄存器设置、挂入DMA等待队列、清除DMA中断、释放DMA通道。Dma.c中对这些工作作了很好的实现,以下具体分析关键函数:

int s3c2410_request_dma(const char *device_id, dmach_t channel, 
dma_callback_t write_cb, dma_callback_t read_cb) (s3c2410_dma_queue_buffer);

函数描述:申请某通道的DMA资源,填充s3c2410_dma_t 数据结构的内容,申请DMA中断。


输入参数:device_id DMA 设备名;channel 通道号;

write_cb DMA写操作完成的回调函数;read_cb DMA读操作完成的回调函数

输出参数:若channel通道已使用,出错返回;否则,返回0

int s3c2410_dma_queue_buffer(dmach_t channel, void *buf_id, 
dma_addr_t data, int size, int write) (s3c2410_dma_stop);

函数描述:这是DMA操作最关键的函数,它完成了一系列动作:分配并初始化一个DMA内核缓冲区控制结构,并将它插入DMA等待队列,设置DMA控制寄存器内容,等待DMA操作触发

输入参数: channel 通道号;buf_id,缓冲区标识

dma_addr_t data DMA数据缓冲区起始物理地址;size DMA数据缓冲区大小;write 是写还是读操作

输出参数:操作成功,返回0;否则,返回错误号

int s3c2410_dma_stop(dmach_t channel) 
函数描述:停止DMA操作。

int s3c2410_dma_flush_all(dmach_t channel) 
函数描述:释放DMA通道所申请的所有内存资源

void s3c2410_free_dma(dmach_t channel) 
函数描述:释放DMA通道

因为各函数功能强大,一个完整的DMA驱动程序中一般只需调用以上3个函数即可。可在驱动初始化中调用s3c2410_request_dma,开始DMA传输前调用s3c2410_dma_queue_buffer,释放驱动模块时调用s3c2410_free_dma。


具体的DMA实例分析 
Linux下的IIS音频驱动主要都在/kernel/drivers/sound/s3c2410-uda1341.c文件中。它定义了2个重要的数据结构audio_bufer_t, 管理audio缓冲区的数据结构;audio_stream_t 管理多缓冲区的数据结构,它为音频流数据组成了一个环形缓冲区。


我们先看一下加载驱动模块时的初始化函数:int __init s3c2410_uda1341_init(void),该函数先初始化IO和UDA341芯片,然后语句s3c2410_request_dma("I2SSDO", s->dma_ch, audio_dmaout_done_callback, NULL);申请了一个DMA通道用于输出音频数据;

smdk2410_audio_write是音频驱动最关键的函数,它从用户进程中拷贝音频数据流至DMA内核缓冲区,然后适用DMA通道2把音频数据发送出去,从而输出声音。我们可以在smdk2410_audio_write 中发现语句s3c2410_dma_queue_buffer(s->dma_ch, (void *) b,b->dma_addr, b->size, DMA_BUF_WR);就是它为DMA写操作作好了一切准备,当I2SSDO中断到来,DMA2通道执行一次写操作(从DMA缓冲写往IO地址0x55000010)。


smdk2410_audio_release函数中先后调用了s3c2410_dma_flush_all、s3c2410_free_dma释放DMA2占用的内存资源、和释放DMA2通道.

//=========================================

 

前天完成了UDA1341的驱动,程序是网上下载的,仅仅小改一下而已,昨晚上
分析了其中的DMA部分,有些小小的感想,如果不正确希望读者能够告诉我。谢谢。
写的很乱,没有整理。


DMA的基础就不介绍了,可以参考http://blog.chinaunix.net/u1/58640/showart_483567.html
和规格书。我主要根据audio的使用,介绍一下DMA的使用。


    1.首先对DMA进行初始化。
    如对outstream的初始化
    channel = 2;
    source = S3C2410_DMASRC_MEM;//源地址为Memory
    hwcfg = 3;                   
    devaddr = 0x55000010;
    dcon = 0xa0800000;
    flags = S3C2410_DMAF_AUTOSTART;
    
/* s3c2410_dma_devconfig
 *
 * configure the dma source/destination hardware type and address
 * 配置DMA的源和目的的硬件类型和地址
 * source:    S3C2410_DMASRC_HW: source is hardware 源是硬件
 *            S3C2410_DMASRC_MEM: source is memory  源是内存
 *
 * hwcfg:     the value for xxxSTCn register,
 *            bit 0: 0=increment pointer, 1=leave pointer
 *            bit 1: 0=soucre is AHB, 1=soucre is APB
 *
 * devaddr:   physical address of the source
*/

因为我们的DMA 源是内存,目的是硬件IIS的固定地址,所以hwcfg应该
设定为APB  FIX_ADDR 即:3
int s3c2410_dma_devconfig(int channel,
              s3c2410_dmasrc_t source,
              int hwcfg,
              unsigned long devaddr)
{undefined
    s3c2410_dma_chan_t *chan = &s3c2410_chans[channel];

    check_channel(channel);

    pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx/n",
         __FUNCTION__, (int)source, hwcfg, devaddr);

    chan->source = source;
    chan->dev_addr = devaddr;

    switch (source) {undefined
    case S3C2410_DMASRC_HW:
        /* source is hardware */
        pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d/n",
             __FUNCTION__, devaddr, hwcfg);
        dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3);
        dma_wrreg(chan, S3C2410_DMA_DISRC,  devaddr);
        dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));

        chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
        return 0;

    case S3C2410_DMASRC_MEM:
        /* source is memory */
        pr_debug( "%s: mem source, devaddr=%08lx, hwcfg=%d/n",
              __FUNCTION__, devaddr, hwcfg);
        dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0));
        dma_wrreg(chan, S3C2410_DMA_DIDST,  devaddr);
        dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);

        chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
        return 0;
    }

    printk(KERN_ERR "dma%d: invalid source type (%d)/n", channel, source);
    return -EINVAL;
}

/* s3c2410_dma_config
 *
 * xfersize:     size of unit in bytes (1,2,4)
 * dcon:         base value of the DCONx register
*/
    dcon = 0xa0800000;
    因为IIS是16bit的,所以unit为2.
    s3c2410_dma_config(channel, 2, dcon);
//设定DMA传输结束后的回调函数
    s3c2410_dma_set_buffdone_fn(channel, audio_dmaout_done_callback);
    //设定S3C2410_DMAF_AUTOSTART
    s3c2410_dma_setflags(channel, flags);
    //申请DMA通道
    ret = s3c2410_dma_request(s->dma_ch, &s3c2410iis_dma_out, NULL);
    
    以上是初始化部分,之后通过dmabuf = dma_alloc_coherent(NULL, dmasize, &dmaphys, GFP_KERNEL);
来申请缓冲,dmabuf为虚拟地址,dmaphys是物理地址,虚拟地址用来让驱动写buf用,dmaphys用来传给dma。
dma关心的是实际的物理地址。
    然后通过s3c2410_dma_enqueue(s->dma_ch, (void *) b, b->dma_addr, b->size);来启动dma传输,
这里面的参数就是dmaphys,它为实际地址。
   如果dma传输结束,就会调用:
static void audio_dmaout_done_callback(s3c2410_dma_chan_t *ch, void *buf, int size,
s3c2410_dma_buffresult_t result)
{undefined
    audio_buf_t *b = (audio_buf_t *) buf;
    DPRINTK("audio_dmaout_done_callback/n");
    up(&b->sem);
    wake_up(&b->sem.wait);
}

来启动下一个buf的传输。


关键字:S3C2440  DMA  工作原理 引用地址:S3C2440 DMA工作原理

上一篇:S3C2410 DMA原理与实例
下一篇:linux下S3C2410的DMA驱动程序开发

推荐阅读最新更新时间:2024-11-10 11:40

S3C2440 nand sdram启动时代码的运行转移过程
在reset期间,S3C2440 Nand Flash控制器通过和nand flash相连的管脚pin的状态获得信息(NCON,GPG13,GPG14,GPG15).启动电源或者系统复位后,NAND Flash控制器 会自动的下载4Kboot loader代码,下载了的boot loader 代码之后就在setppingstone 开始执行了。 S3C2440的boot code能够在外部的nand flash内存中执行。为了支持nand flash 的boot 引导,S3C2440有一个内部的SDRAM缓存称为“Steppingstone”,当booting的时候,Nand Flash的首4kbyte会被导入到Stepping
[单片机]
自动驾驶领域点云配准的工作原理与技术方法
在第一篇《详解激光雷达点云数据的处理过程》和第二篇《激光雷达点云处理中遇到的问题及对策》的激光点云系列文中,笔者分别分析了激光雷达的点云处理流程和点云处理环节中遇到的典型问题及对策。在本篇文章中,笔者将重点分析激光点云在定位环节中的点云配准技术。 由于受到视场角的限制,激光雷达在实时采集点云数据时,只能获得有限视野范围内的点云图像。为了获得三维场景的点云数据,感知算法人员需要在已知的初始姿态信息下,将采集到的前后两帧不同点云转换到统一坐标系下,将点云重合的部分拼接在一起——这就是点云配准技术。 下文将逐一分析点云配准具体是什么、点云配准的技术方法、点云配准面临的问题及对策。 01 点云配准在自动驾驶方面的应用 点云配准
[嵌入式]
自动驾驶领域点云配准的<font color='red'>工作原理</font>与技术方法
基于32位ARM嵌入式微控制器S3C2440来构建太阳跟踪系统
  基于计算机视觉原理,以ARM微控制器为核心构建嵌入式图像处理平台,实现了对太阳的实时跟踪。系统采用CMOS图像传感器采集太阳图像,通过微控制器计算太阳角度,通过串口控制转台,实现对太阳的高精度跟踪。同时,与视日运动规律相结合,保证系统的可靠性。试验表明,该系统在降低系统能耗的同时,能可靠有效地跟踪太阳运动。   随着社会的发展和进步,环保节能已经成为人类可持续发展的必要条件。目前,再生能源的开发和利用越来越受到人们的关注。太阳能由于其普遍、无害、无限、长久等特点,成为最绿色、最理想、最可靠的替代能源。但太阳能同时存在分散,不稳定,效率低等特点,太阳能光伏系统为解决这一问题提供了条件。   就目前的太阳能光伏系统而言,如何最
[单片机]
基于32位ARM嵌入式微控制器<font color='red'>S3C2440</font>来构建太阳跟踪系统
基于S3C2440和DM9000移植LWIP
终于开始我的第一篇笔记了。这回要做的事情,是以太网的移植。 使用mini2440已经有一段时间了。诸如裸机的LED,键盘开关等等等等也都试验过了,uCOS,WinCE也是浅尝了一下。如今想到了以太网。 由于mini2440的板上集成了一个DM9000的网卡,并且在CE系统里面成功的使用以太网与PC连接了。于是自然而然的想,能不能在uCOS下也实现以太网接口呢? 一上来什么都不懂,于是找一些资料,在这里要谢谢焦海波老师所著的嵌入式网络系统设计一书,移植过程中很多资料都来源于这本书。其次是mikenoodle的单片机驱动DM9000网卡一文,里面详细地讲述如何在2440裸机下驱动DM9000网卡。 首先明确我们需要做的事情是什么?为了
[单片机]
直流变频器的工作原理
变频器是电子产品中常用的一种元件,那您知道变频器工作原理是怎样的么? 变频器原理(英文Variable-frequency Drive,简称VFD)是应用变频技术与微电子技术的原理,通过改变电机工作电源频率的方式来控制交流电动机的电力控制设备。使用的电源分为交流电源和直流电源,一般的直流电源大多是由交流电源通过变压器变压,整流滤波后得到的。交流电源在人们使用电源中占总使用电源的95%左右。 变频器由主电路(包括整流器、中间直流环节、逆变器)和控制回路组成。各部分的功能如下: 1. 整流器 它的作用是把三相(或单相)交流电源整流成直流电。在SPWM变频器中,大多采用全波整流电路。大多数中、小容量的变频器中,整流器件采用不能控
[嵌入式]
直流变频器的<font color='red'>工作原理</font>
变频调速器的工作原理分析
变频调速器是一种电力电子器件,用于控制电机的转速和扭矩。其主要工作原理是将交流电源通过整流电路转换为直流电,再通过逆变电路将直流电转换为带有可调频率、幅值和相位的交流电输出。这个输出可以通过调整控制电路和逆变电路中的信号实现对电机的控制。 具体来说,变频调速器的工作可以分为三个阶段: 1.整流:将电网输入的交流电转换为直流电,用于供给逆变电路。 2.逆变:逆变电路将直流电转换为交流电,输出频率、相位、幅值可调的变频电流,控制电机的输出转速。 3.控制:通过传感器将电机的运行状态反馈给控制电路,进行比较和运算,校正输出信号和控制电机的转速。 总之,变频调速器的控制电路能够根据输入信号来调整电机的转速,从而实现对电机的精确控制
[嵌入式]
交流电压测量电路的工作原理
交流电压测量电路中的整流装置与交流电流测量电路中的整流装置相似。因而在具有交流电流和交流电压测量功能的万用表中都是共用一套整流器件。交流电压测量中,扩大量程用的倍率器结构与直流电压测量用的倍率器相同(由倍率电阻组成的等比例变值电路被称为倍率器;由于电阻具有时间常数的特性,所以倍率器也具有时间常数的特性),如图1所示。一般万用表都采用先降压后整流的方式。     图1 交流电压测量原理 a)串阻抽头半波整流式 b)串阻抽头全波整流式 c)独立分挡半波整流式 d)独立分挡全波整流式 测量交流电压时,其工作频率提高时,由于倍率器的时间常数不同和电路的分布电容会使仪表产生附加误差。在有些万用表中,高电压挡采用电容补偿法来扩大频率范围,若
[电源管理]
交流电压测量电路的<font color='red'>工作原理</font>
变频器的作用_变频器工作原理
变频器是把工频电源(50Hz或60Hz)变换成各种频率的交流电源,以实现电机的变速运行的设备,其中控制电路完成对主电路的控制,整流电路将交流电变换成直流电,直流中间电路对整流电路的输出进行平滑滤波,逆变电路将直流电再逆成交流电。对于如矢量控制变频器这种需要大量运算的变频器来说,有时还需要一个进行转矩计算的CPU以及一些相应的电路。变频调速是通过改变电机定子绕组供电的频率来达到调速的目的。 变频器的分类方法有多种,按照主电路工作方式分类,可以分为电压型变频器和电流型变频器;按照开关方式分类,可以分为PAM控制变频器、PWM控制变频器和高载频PWM控制变频器;按照工作原理分类,可以分为V/f控制变频器、转差频率控制变频器和矢量控制
[嵌入式]
变频器的作用_变频器<font color='red'>工作原理</font>
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved