打印
[DSP编程]

McBSP和DMA接口的问题,不明白,希望各位指点下

[复制链接]
3383|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
最近在学McBSP和DMA,TI的官方例程中,有一个例程是
McBSP工作在数字回环模式下,同步接收DMA通道2的数据,在这个例程中有个问题不明白

    /* Wait for DMA transfer to be complete */
    while (!DMA_FGETH(mhDma,DMACSR,FRAME)) {
        ;   
    }//为什么这条语句结束才表明数据收发完成?
   
这里的“同步”是什么意思?是McBSP模块内部进行数据传输的同时,还可以接收来自DMA的数据,如果是这样的话,接收的DMA数据是
作为写入到DXR中的数据还是其他的?
*************************************************************************************************************************
/*
* Copyright (C) 2003 Texas Instruments Incorporated
* All Rights Reserved
*/
/*
*---------main_dma3.c---------
* This example places the MCBSP in digital loopback mode and
* syncs MCBSP receive with DMA channel 2.                  
* The example uses predefined CSL macros and symbolic      
* constants to create the initialization values needed for  
* the MCBSP and DMA control registers to effect the transfer
*/
/*************************************************************************
*实验说明:将MCBSP置于数字回环模式,并且同步接收DMA通道2的数据,实验中仍然
*使用预先定义的CSL宏和符号常量来进行相关控制寄存器的初始化
*************************************************************************/
#include <stdio.h>

#include <csl_mcbsp.h>
#include <csl_dma.h>
#include <csl_irq.h>

//---------Global constants---------
#define N       128

//---------Global data definition---------
/* Define transmit and receive buffers */
#pragma DATA_SECTION(rcv,"dmaMem")
Uint16 xmt[N], rcv[N];


  MCBSP_Config ConfigLoopBack16= {
  MCBSP_SPCR1_RMK(
    MCBSP_SPCR1_DLB_ON,                    /* DLB    = 1 */
    MCBSP_SPCR1_RJUST_RZF,                 /* RJUST  = 0 */
    MCBSP_SPCR1_CLKSTP_DISABLE,            /* CLKSTP = 0 */
    MCBSP_SPCR1_DXENA_NA,                  /* DXENA  = 0 */
    MCBSP_SPCR1_ABIS_DISABLE,              /* ABIS   = 0 */
    MCBSP_SPCR1_RINTM_RRDY,                /* RINTM  = 0 */
    0,                                     /* RSYNCER = 0 */
    MCBSP_SPCR1_RRST_DISABLE               /* RRST   = 0 */
   ),
    MCBSP_SPCR2_RMK(
    MCBSP_SPCR2_FREE_NO,                   /* FREE   = 0 */
    MCBSP_SPCR2_SOFT_NO,                   /* SOFT   = 0 */
    MCBSP_SPCR2_FRST_RESET,                /* FRST   = 0 帧同步*/
    MCBSP_SPCR2_GRST_RESET,                /* GRST   = 0 */
    MCBSP_SPCR2_XINTM_XRDY,                /* XINTM  = 0 */
    0,                                     /* XSYNCER = N/A */
    MCBSP_SPCR2_XRST_DISABLE               /* XRST   = 0 */
   ),
  MCBSP_RCR1_RMK(
  MCBSP_RCR1_RFRLEN1_OF(0),                /* RFRLEN1 = 0 */
  MCBSP_RCR1_RWDLEN1_16BIT                 /* RWDLEN1 = 5 */
  ),
MCBSP_RCR2_RMK(   
    MCBSP_RCR2_RPHASE_SINGLE,              /* RPHASE  = 0 */
    MCBSP_RCR2_RFRLEN2_OF(0),              /* RFRLEN2 = 0 */
    MCBSP_RCR2_RWDLEN2_8BIT,               /* RWDLEN2 = 0 */
    MCBSP_RCR2_RCOMPAND_MSB,               /* RCOMPAND = 0 */
    MCBSP_RCR2_RFIG_YES,                   /* RFIG    = 0 */
    MCBSP_RCR2_RDATDLY_0BIT                /* RDATDLY = 0 数据接收延时*/
    ),  
   MCBSP_XCR1_RMK(   
    MCBSP_XCR1_XFRLEN1_OF(0),              /* XFRLEN1 = 0 */
    MCBSP_XCR1_XWDLEN1_16BIT               /* XWDLEN1 = 5 发送阶段1的字长为16位*/
   
),   
MCBSP_XCR2_RMK(   
    MCBSP_XCR2_XPHASE_SINGLE,              /* XPHASE  = 0 */
    MCBSP_XCR2_XFRLEN2_OF(0),              /* XFRLEN2 = 0 */
    MCBSP_XCR2_XWDLEN2_8BIT,               /* XWDLEN2 = 0 */
    MCBSP_XCR2_XCOMPAND_MSB,               /* XCOMPAND = 0 */
    MCBSP_XCR2_XFIG_YES,                   /* XFIG    = 0 */
    MCBSP_XCR2_XDATDLY_0BIT                /* XDATDLY = 0 */
  ),            
MCBSP_SRGR1_RMK(
   MCBSP_SRGR1_FWID_OF(1),                /* FWID    = 1 */
   MCBSP_SRGR1_CLKGDV_OF(1)               /* CLKGDV  = 1 */
),   
MCBSP_SRGR2_RMK(  
    MCBSP_SRGR2_GSYNC_FREE,                /* FREE    = 0 */
    MCBSP_SRGR2_CLKSP_RISING,              /* CLKSP   = 0 */
    MCBSP_SRGR2_CLKSM_INTERNAL,            /* CLKSM   = 1 */
    MCBSP_SRGR2_FSGM_DXR2XSR,              /* FSGM    = 0 */
    MCBSP_SRGR2_FPER_OF(15)                /* FPER    = 0 */
),  
MCBSP_MCR1_DEFAULT,
MCBSP_MCR2_DEFAULT,
MCBSP_PCR_RMK(
   MCBSP_PCR_IDLEEN_RESET,                 /* IDLEEN   = 0   */
   MCBSP_PCR_XIOEN_SP,                     /* XIOEN    = 0   */
   MCBSP_PCR_RIOEN_SP,                     /* RIOEN    = 0   */
   MCBSP_PCR_FSXM_INTERNAL,                /* FSXM     = 1   */
   MCBSP_PCR_FSRM_EXTERNAL,                /* FSRM     = 0   */
   MCBSP_PCR_CLKXM_OUTPUT,                 /* CLKXM    = 1   */
   MCBSP_PCR_CLKRM_INPUT,                  /* CLKRM    = 0   */
   MCBSP_PCR_SCLKME_NO,                    /* SCLKME   = 0   */
   0,                                      /* DXSTAT = N/A   */
   MCBSP_PCR_FSXP_ACTIVEHIGH,              /* FSXP     = 0   */
   MCBSP_PCR_FSRP_ACTIVEHIGH,              /* FSRP     = 0   */
   MCBSP_PCR_CLKXP_RISING,                 /* CLKXP    = 0   */
   MCBSP_PCR_CLKRP_FALLING                 /* CLKRP    = 0   */
),
MCBSP_RCERA_DEFAULT,
MCBSP_RCERB_DEFAULT,
MCBSP_RCERC_DEFAULT,
MCBSP_RCERD_DEFAULT,
MCBSP_RCERE_DEFAULT,
MCBSP_RCERF_DEFAULT,
MCBSP_RCERG_DEFAULT,
MCBSP_RCERH_DEFAULT,
MCBSP_XCERA_DEFAULT,
MCBSP_XCERB_DEFAULT,
MCBSP_XCERC_DEFAULT,
MCBSP_XCERD_DEFAULT,  
MCBSP_XCERE_DEFAULT,
MCBSP_XCERF_DEFAULT,  
MCBSP_XCERG_DEFAULT,
MCBSP_XCERH_DEFAULT
};     

/* Create DMA Receive Side Configuration */
DMA_Config  dmaConfig = {
  DMA_DMACSDP_RMK(
    DMA_DMACSDP_DSTBEN_NOBURST,
    DMA_DMACSDP_DSTPACK_OFF,
    DMA_DMACSDP_DST_DARAM,                  /*目的端口为DARAM*/
    DMA_DMACSDP_SRCBEN_NOBURST,
    DMA_DMACSDP_SRCPACK_OFF,
    DMA_DMACSDP_SRC_PERIPH,                /*源端口为 外设*/
    DMA_DMACSDP_DATATYPE_16BIT
  ),                                       /* DMACSDP  */
  DMA_DMACCR_RMK(
    DMA_DMACCR_DSTAMODE_POSTINC,
    DMA_DMACCR_SRCAMODE_CONST,
    DMA_DMACCR_ENDPROG_ON,          /*传输过程可以对配置寄存器进行编程*/
    DMA_DMACCR_REPEAT_OFF,
    DMA_DMACCR_AUTOINIT_OFF,
    DMA_DMACCR_EN_STOP,
    DMA_DMACCR_PRIO_LOW,             /*通道优先级低*/
    DMA_DMACCR_FS_DISABLE,          /*帧同步禁止*/
    DMA_DMACCR_SYNC_REVT1           /*DMA同步事件*/
  ),                                       /* DMACCR   */
  DMA_DMACICR_RMK(
    DMA_DMACICR_BLOCKIE_OFF,
    DMA_DMACICR_LASTIE_OFF,
    DMA_DMACICR_FRAMEIE_ON,   /*半帧中断使能*/
    DMA_DMACICR_FIRSTHALFIE_OFF,
    DMA_DMACICR_DROPIE_OFF,      /*同步事件旁落使能关闭*/
    DMA_DMACICR_TIMEOUTIE_OFF   /*超时中断使能关闭*/
  ),                                       /* DMACICR  */
    (DMA_AdrPtr)(MCBSP_ADDR(DRR11)),        /* DMACSSAL */
    0,                                     /* DMACSSAU */
    (DMA_AdrPtr)&rcv,                      /* DMACDSAL */
    0,                                     /* DMACDSAU */
    N,                                     /* DMACEN   */
    1,                                     /* DMACFN   */
    0,                                     /* DMACFI   */
    0                                      /* DMACEI   */
};

/* Define a DMA_Handle object to be used with DMA_open function */
DMA_Handle mhDma;

/* Define a MCBSP_Handle object to be used with MCBSP_open function */
MCBSP_Handle mhMcbsp;

volatile Uint16 xfrCnt = 0;
Uint16 err = 0;
Uint16 old_intm;
Uint16 xmtEventId;

//---------Function prototypes---------
/* Protoype for MCBSP transmit interrupt function */
interrupt void mcbspIsr(void);
void taskFxn(void);

//---------main routine---------
void main(void)
{
    Uint16 i;

    /* Initialize CSL library - This is REQUIRED !!! */
    CSL_init();

    /* Initialize data for transfer */
    for (i = 0; i <= N - 1; i++) {  
        xmt[i] =  i + 1;
        rcv[i] = 0;
    }

    /* Call function to effect transfer */
    taskFxn();
}

void taskFxn(void)
{
    Uint16 srcAddrHi, srcAddrLo;
    Uint16 dstAddrHi, dstAddrLo;
    Uint16 i;

    /* By default, the TMS320C55xx compiler assigns all data symbols word */
    /* addresses. The DMA however, expects all addresses to be byte       */
    /* addresses. Therefore, we must shift the address by 2 in order to   */
    /* change the word address to a byte address for the DMA transfer.    */
    srcAddrHi = (Uint16)(((Uint32)(MCBSP_ADDR(DRR11))) >> 15) & 0xFFFFu;
    srcAddrLo = (Uint16)(((Uint32)(MCBSP_ADDR(DRR11))) << 1) & 0xFFFFu;
    dstAddrHi = (Uint16)(((Uint32)(&rcv)) >> 15) & 0xFFFFu;
    dstAddrLo = (Uint16)(((Uint32)(&rcv)) << 1) & 0xFFFFu;

    dmaConfig.dmacssal = (DMA_AdrPtr)srcAddrLo;
    dmaConfig.dmacssau = srcAddrHi;
    dmaConfig.dmacdsal = (DMA_AdrPtr)dstAddrLo;
    dmaConfig.dmacdsau = dstAddrHi;

    /* Open MCBSP Port 1 and set registers to their power on defaults */
    mhMcbsp = MCBSP_open(MCBSP_PORT1, MCBSP_OPEN_RESET);
   
    /* Get interrupt event assoicated MCBSP transmit */
    xmtEventId = MCBSP_getXmtEventId(mhMcbsp);
   
    /* Temporarily disable interrupts and clear any pending */
    /* interrupts for MCBSP transmit */
    old_intm = IRQ_globalDisable();
    IRQ_clear(xmtEventId);

    /* Enable MCBSP transmit interrupt in IER register */
    IRQ_enable(xmtEventId);
   
    /* Set Start Of Interrupt Vector Table */
    IRQ_setVecs(0x10000);

    /* Place address for MCBSP transmit interrupt service routine */
    /* in associated vector location */
    IRQ_plug(xmtEventId,&mcbspIsr);

    /* Open DMA Channel 2 and set registers to their power on defaults */
    mhDma = DMA_open(DMA_CHA2,DMA_OPEN_RESET);   

    /* Write values from configuration structure to MCBSP control regs */
    MCBSP_config(mhMcbsp, &ConfigLoopBack16);
   
    /* Write values from configuration structure to DMA control regs */
    DMA_config(mhDma,&dmaConfig);
   
    /* Enable all maskable interrupts */
    IRQ_globalEnable();

    /* Start MCBSP */
    MCBSP_start(mhMcbsp,               
               MCBSP_SRGR_START|MCBSP_SRGR_FRAMESYNC,0x300u);

    /* Enable DMA */
    DMA_start(mhDma);
   
        /* Take MCBSP transmit annd receive out of reset 发送和接收复位*/
    MCBSP_start(mhMcbsp,
                MCBSP_XMIT_START| MCBSP_RCV_START,  
                0);

    /* Wait for DMA transfer to be complete */
    while (!DMA_FGETH(mhDma,DMACSR,FRAME)) {
        ;   
    }//为什么这条语句结束才表明数据收发完成?
   
    /*------------------------------------------*\
     * Compare values 所有数据发送和接收都完毕之后,
          检测数据收发有没有错误
    \*------------------------------------------*/   
    for(i = 0; i <= N - 1; i++){
        if (rcv[i] != xmt[i]){
            ++err;
            break;
       }
    }

    printf ("%s\n",err?"TEST FAILED" : "TEST PASSED");

    /* Restore status of global interrupt enable flag */
    IRQ_globalRestore(old_intm);
        
    /* We're done with MCBSP and DMA , so close them */
    MCBSP_close(mhMcbsp);
    DMA_close(mhDma);                     
}

/* MCBSP transmit interrupt service routine */
/*MCBSP发送中断服务子程序*/
interrupt void mcbspIsr(void) {
  
  if (xfrCnt < N) {
     MCBSP_write16(mhMcbsp,xmt[xfrCnt]); /*当发送准备好后,进入中断写数据*/
      ++xfrCnt;
  }
  else {
     MCBSP_FSETH(mhMcbsp,SPCR2,XRST,0);
  }
}

相关帖子

沙发
zhangmangui| | 2014-5-7 22:28 | 只看该作者
@以马内利3005   帮忙解答一下

使用特权

评论回复
板凳
以马内利3005| | 2014-5-8 19:52 | 只看该作者
zhangmangui 发表于 2014-5-7 22:28
@以马内利3005   帮忙解答一下

while (!DMA_FGETH(mhDma,DMACSR,FRAME)) {
        ;   
    }
这条语句是的意思是,如果  DMA_FGETH(mhDma,DMACSR,FRAME) 的值是0,程序会一直停在此语句上,直到其值变为1。
DMA_FGETH()是一个宏函数,功能是读取某个寄存器的某个域的值,这里就是读取DMACSR寄存器的FRAME域的值。
FRAME域的值所代表的意思参考下面的图片,摘自官方DMA文档
当FRAME的值为1的时候,说明整个一帧的数据已经全部传输完毕了。
@ttxs_2013  

使用特权

评论回复
评分
参与人数 1威望 +4 收起 理由
zhangmangui + 4 赞一个!
地板
ttxs_2013|  楼主 | 2014-5-11 20:31 | 只看该作者
以马内利3005 发表于 2014-5-8 19:52
while (!DMA_FGETH(mhDma,DMACSR,FRAME)) {
        ;   
    }

这个我知道,我不明白的是”同步“结合到这个例程是怎么理解的?就是我问的第二个问题【“同步”是什么意思?是McBSP模块内部进行数据传输的同时,还可以接收来自DMA的数据,如果是这样的话,接收的DMA数据是
作为写入到DXR中的数据还是其他的?】,我感觉自己还没理解,没有真正弄清楚。希望前辈可以解释下,谢谢!

使用特权

评论回复
5
以马内利3005| | 2014-5-12 16:17 | 只看该作者
ttxs_2013 发表于 2014-5-11 20:31
这个我知道,我不明白的是”同步“结合到这个例程是怎么理解的?就是我问的第二个问题【“同步”是什么意 ...

这个例程里面用到的DMA是接收来自MCBSP的数据并传送到rcv,MCBSP的发送数据是CPU直接写进去的,经过回环到达MCBSP的接收端,又传给了DMA,最终到达rcv,所以我认为此处的注释有问题,官方例程怎么会有中文注释呢,应该是别人在学习的时候加的,而且是错误的。你就不用纠结这里的“同步”了!

使用特权

评论回复
6
ttxs_2013|  楼主 | 2014-5-13 20:56 | 只看该作者
以马内利3005 发表于 2014-5-12 16:17
这个例程里面用到的DMA是接收来自MCBSP的数据并传送到rcv,MCBSP的发送数据是CPU直接写进去的,经过回环 ...

难怪,我就是说如果理解成DMA写数据到McBSP,那中断里面也是写数据,不就多余了。。。(中文是我在学习时候注释的,实验说明是按照英文翻译过来,所以沿着McBSP同步接收DMA通道2的数据 这一思路来学的,理解不过去,于是就想是不是自己DMA同步没理解,看来是翻译有问题,导致理解错误)多谢了

使用特权

评论回复
7
以马内利3005| | 2014-5-13 22:17 | 只看该作者
ttxs_2013 发表于 2014-5-13 20:56
难怪,我就是说如果理解成DMA写数据到McBSP,那中断里面也是写数据,不就多余了。。。(中文是我在学习时 ...

:handshake:D

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

31

主题

125

帖子

4

粉丝