搜索
bottom↓
回复: 4

DM642+MCBSP+EDMA pingpong采集音频数据请教

[复制链接]

出0入0汤圆

发表于 2012-10-29 17:00:55 | 显示全部楼层 |阅读模式
各位大侠:
    我做DM642+MCBSP+EDMA pingpong采集音频时候,总是停在  while (!MCBSP_xrdy(hMcbsp));这一句话,想请教各位是不是我设置的不对啊,下面是我的程序:
/*
*  Copyright 2003 by Texas Instruments Incorporated.
*  All rights reserved. Property of Texas Instruments Incorporated.
*  Restricted rights to use, duplicate or disclose this code are
*  granted through contract.
*  
*/
/* "@(#) DSP/BIOS 4.90.270 06-11-03 (barracuda-m10)" */
/*
*  Copyright 2001 by Texas Instruments Incorporated.
*  All rights reserved. Property of Texas Instruments Incorporated.
*  Restricted rights to use, duplicate or disclose this code are
*  granted through contract.
*  U.S. Patent Nos. 5,283,900  5,392,448
*/
/* "@(#) DSP/BIOS 4.51.0 05-23-01 (barracuda-i10)" */
/******************************************************************************\
*           Copyright (C) 2000 Texas Instruments Incorporated.
*                           All Rights Reserved
*------------------------------------------------------------------------------
* FILENAME...... main.c
* DATE CREATED.. 10/02/2000
* LAST MODIFIED. 02/02/2002
*------------------------------------------------------------------------------
* This program uses the timers to trigger EDMA events. These events in turn
* trigger linked EDMA parameter tables to fill a ping pong buffer structure.
* Set a breakpoint on swiProcessFunc(int arg). Then open two memory windows.
* Use ping as the address for one memory window and pong for the other. Then
* run the application. You'll note that the program bounces between the ping
* and pong buffers filling each with a value that comes from the source. The
* source in this case is the SDRAM timer control register and it simulates
* input data.(Note: This example runs with CACHE enable).
\******************************************************************************/
#include <std.h>
#include <swi.h>
#include <log.h>
#include <clk.h>
#include <stdio.h>
#include <csl.h>
#include <csl_cache.h>
#include <csl_edma.h>
#include <csl_irq.h>
#include <csl_mcbsp.h>
#include <csl_mcbsphal.h>
#include "aic23.h"
/*----------------------------------------------------------------------------*/

/* declare DSP/BIOS objects created with the configuration tool */
extern far SWI_Obj SwiMain;
extern far LOG_Obj LogMain;
extern far SWI_Obj swiProcess;
extern far LOG_Obj trace;

/* Pick which EDMA transfer completion interrupt we want to use */
#define TCCINTNUM   13

/* define some constants */
#define BUFF_SZ  256              /* ping-pong buffer sizes in # of ints  */
#define FCPU     150000000        /* CPU clock frequency                  */
#define SRATE    8000             /* data sample rate (simulated w/timer  */
#define TPRD     (FCPU/(4*SRATE)) /* timer period                         */

/* Create the buffers. We want to align the buffers to be cache friendly */
/* by aligning them on an L2 cache line boundary.                        */
#pragma DATA_ALIGN(ping,128);
#pragma DATA_ALIGN(pong,128);
#pragma DATA_ALIGN(outbuff,128);
int ping[BUFF_SZ];
int pong[BUFF_SZ];
int outbuff[BUFF_SZ];

/* These two variables serve as the data sources for this example. */
/* Also want to align these on a cache line boundary since they    */
/* sources of EDMA transfers.                                      */
#pragma DATA_ALIGN(ping_data,128);
#pragma DATA_ALIGN(pong_data,128);
static int ping_data;
static int pong_data;

/* global variable used to track the ping-pong'ing */
static int pingpong = 0;

MCBSP_Handle hMcbsp0;                 // McBSP0 句柄  
/* declare some CSL objects */
EDMA_Handle hEdma;     /* Handle for the EDMA channel                 */
EDMA_Handle hEdmaPing; /* Handle for the ping EDMA reload parameters  */
EDMA_Handle hEdmaPong; /* Handle for the pong EDMA reload parameters  */
EDMA_Config cfgEdma;   /* EDMA configuration structure                */

/* Create the EDMA configuration structure for ping transfers */
EDMA_Config cfgEdmaPing = {  
  EDMA_OPT_RMK(
    EDMA_OPT_PRI_LOW,       //低优先级EDMA传输
    EDMA_OPT_ESIZE_32BIT,   //单元大小
    EDMA_OPT_2DS_NO,        //源维数,一维
    EDMA_OPT_SUM_NONE,      //源地址更新模式,固定地址模式
    EDMA_OPT_2DD_NO,        //目的单元维数,一维
    EDMA_OPT_DUM_INC,       //
    EDMA_OPT_TCINT_YES,
    EDMA_OPT_TCC_OF(TCCINTNUM),
    EDMA_OPT_TCCM_OF(0),
    EDMA_OPT_ATCINT_NO,
    EDMA_OPT_ATCC_OF(0),
    EDMA_OPT_PDTS_DEFAULT,
    EDMA_OPT_PDTD_DEFAULT,
    EDMA_OPT_LINK_YES,
    EDMA_OPT_FS_NO
  ),
  EDMA_SRC_OF(_MCBSP_DRR0_ADDR),
  EDMA_CNT_OF(BUFF_SZ),
  EDMA_DST_OF(ping),
  EDMA_IDX_OF(0x00000004),
  EDMA_RLD_OF(0x00000000)
};                        

/* Create the EDMA configuration structure for pong transfers */
EDMA_Config cfgEdmaPong = {
  EDMA_OPT_RMK(
    EDMA_OPT_PRI_LOW,
    EDMA_OPT_ESIZE_32BIT,
    EDMA_OPT_2DS_NO,
    EDMA_OPT_SUM_NONE,
    EDMA_OPT_2DD_NO,
    EDMA_OPT_DUM_INC,
    EDMA_OPT_TCINT_YES,
    EDMA_OPT_TCC_OF(TCCINTNUM),
    EDMA_OPT_TCCM_OF(0),
    EDMA_OPT_ATCINT_NO,
    EDMA_OPT_ATCC_OF(0),
    EDMA_OPT_PDTS_DEFAULT,
    EDMA_OPT_PDTD_DEFAULT,
    EDMA_OPT_LINK_YES,
    EDMA_OPT_FS_NO
  ),
  EDMA_SRC_OF(_MCBSP_DRR0_ADDR),
  EDMA_CNT_OF(BUFF_SZ),
  EDMA_DST_OF(pong),
  EDMA_IDX_OF(0x00000004),
  EDMA_RLD_OF(0x00000000)
};

                        
static MCBSP_Config mcbspCfg0 = {
/* 配置McBSP 串行口控制寄存器 */
        MCBSP_FMKS(SPCR, FREE, NO)              |//禁止串行时钟自由运行模式
        MCBSP_FMKS(SPCR, SOFT, NO)              |//仿真停止,串行口时钟立即停止
        MCBSP_FMKS(SPCR, FRST, YES)             |//帧同步发生器复位
        MCBSP_FMKS(SPCR, GRST, YES)             |//采样率发生器复位
        MCBSP_FMKS(SPCR, XINTM, XRDY)           |//传输中断由事件XRDY驱动
        MCBSP_FMKS(SPCR, XSYNCERR, NO)          |//无帧同步发送错误
        MCBSP_FMKS(SPCR, XRST, YES)             |//使能串行口发送
        MCBSP_FMKS(SPCR, DLB, OFF)              |//禁止数字链路回馈模式
        MCBSP_FMKS(SPCR, RJUST, RZF)            |//接收数据无符号扩展,右对其,高位补0
        MCBSP_FMKS(SPCR, CLKSTP, DISABLE)       |//禁止时钟停止模式
        MCBSP_FMKS(SPCR, DXENA, OFF)            |//禁止DX管脚使能
        MCBSP_FMKS(SPCR, RINTM, RRDY)           |//接收中断右事件RRDY驱动
        MCBSP_FMKS(SPCR, RSYNCERR, NO)          |//无帧同步接收错误
        MCBSP_FMKS(SPCR, RRST, YES),             //使能串行口接收
        
/* 配置McBSP接收控制寄存器 */
        MCBSP_FMKS(RCR, RPHASE, SINGLE)         |//接收一相
        MCBSP_FMKS(RCR, RFRLEN2, DEFAULT)       |//第二相接收帧长度
        MCBSP_FMKS(RCR, RWDLEN2, DEFAULT)       |//第二相接收帧中数据单元长度
        MCBSP_FMKS(RCR, RCOMPAND, MSB)          |//接收时无压缩扩展,由最高位开始传输
        MCBSP_FMKS(RCR, RFIG, NO)               |//忽略突发接收帧同步信号
        MCBSP_FMKS(RCR, RDATDLY, 2BIT)          |//接收时数据延迟2位
        MCBSP_FMKS(RCR, RFRLEN1, OF(1))         |//第一相接收帧长度每相两个字长
        MCBSP_FMKS(RCR, RWDLEN1, 32BIT)         |//第一相接收单元长度16bit
        MCBSP_FMKS(RCR, RWDREVRS, DEFAULT),      //禁止32bit接收单元位颠倒
        
/* 配置McBSP 发送控制寄存器 */
        MCBSP_FMKS(XCR, XPHASE, SINGLE)         |
        MCBSP_FMKS(XCR, XFRLEN2, DEFAULT)       |
        MCBSP_FMKS(XCR, XWDLEN2, DEFAULT)       |
        MCBSP_FMKS(XCR, XCOMPAND,MSB)           |
        MCBSP_FMKS(XCR, XFIG, NO)               |
        MCBSP_FMKS(XCR, XDATDLY, 2BIT)          |
        MCBSP_FMKS(XCR, XFRLEN1, OF(1))         |
        MCBSP_FMKS(XCR, XWDLEN1, 32BIT)         |
        MCBSP_FMKS(XCR, XWDREVRS, DEFAULT),      
        
/* 配置McBSP 采样率产生寄存器 */        
        MCBSP_FMKS(SRGR, GSYNC, DEFAULT)        |
            MCBSP_FMKS(SRGR, CLKSP, DEFAULT)        |
            MCBSP_FMKS(SRGR, CLKSM, DEFAULT)        |
            MCBSP_FMKS(SRGR, FSGM, DEFAULT)         |
            MCBSP_FMKS(SRGR, FPER, DEFAULT)         |
            MCBSP_FMKS(SRGR, FWID, DEFAULT)         |
            MCBSP_FMKS(SRGR, CLKGDV, DEFAULT),

        
/* 配置McBSP 多通道控制寄存器 */
        MCBSP_MCR_DEFAULT,
         
/* 配置McBSP 接收通道使能寄存器 */                           
       // MCBSP_RCER_DEFAULT,
         
/* 配置McBSP 发送通道使能寄存器 */                           
        //MCBSP_XCER_DEFAULT,  
        MCBSP_RCERE0_DEFAULT,
                MCBSP_RCERE1_DEFAULT,
                MCBSP_RCERE2_DEFAULT,
                MCBSP_RCERE3_DEFAULT,
                MCBSP_XCERE0_DEFAULT,
                MCBSP_XCERE1_DEFAULT,
                MCBSP_XCERE2_DEFAULT,
                MCBSP_XCERE3_DEFAULT,                    
        
/* 配置McBSP引脚控制寄存器 */
        MCBSP_FMKS(PCR, XIOEN, SP)              |//串行发送模式
        MCBSP_FMKS(PCR, RIOEN, SP)              |//串行接收模式
        MCBSP_FMKS(PCR, FSXM, INTERNAL)         |//内部帧同步发送
        MCBSP_FMKS(PCR, FSRM, EXTERNAL)         |//外部帧同步接收
        MCBSP_FMKS(PCR, CLKXM, OUTPUT)          |//CLKX输出发送时钟
        MCBSP_FMKS(PCR, CLKRM, INPUT)           |//CLKR输入接收时钟
        MCBSP_FMKS(PCR, CLKSSTAT, DEFAULT)      |//CLKS管脚状态
        MCBSP_FMKS(PCR, DXSTAT, DEFAULT)        |//DX管脚状态
        MCBSP_FMKS(PCR, FSXP, ACTIVEHIGH)       |//发送帧同步信号高电平有效
        MCBSP_FMKS(PCR, FSRP, ACTIVEHIGH)       |//接收帧同步信号高电平有效
        MCBSP_FMKS(PCR, CLKXP, RISING)         |//发送时钟上升沿触发数据发送
        MCBSP_FMKS(PCR, CLKRP, FALLING)           //接收时钟下降沿触发数据接收
};

   
/* Codec configuration settings */
AIC23_Params config = { \
    0x0017,  /* 0 DSK6416_AIC23_LEFTINVOL  Left line input channel volume */ \
    0x0017,  /* 1 DSK6416_AIC23_RIGHTINVOL Right line input channel volume */\
    0x01f9,  /* 2 DSK6416_AIC23_LEFTHPVOL  Left channel headphone volume */  \
    0x01f9,  /* 3 DSK6416_AIC23_RIGHTHPVOL Right channel headphone volume */ \
    0x0011,  /* 4 DSK6416_AIC23_ANAPATH    Analog audio path control */      \
    0x0000,  /* 5 DSK6416_AIC23_DIGPATH    Digital audio path control */     \
    0x0000,  /* 6 DSK6416_AIC23_POWERDOWN  Power down control */             \
    0x0043,  /* 7 DSK6416_AIC23_DIGIF      Digital audio interface format */ \
    0x0082,  /* 8 DSK6416_AIC23_SAMPLERATE Sample rate control */            \
    0x0001   /* 9 DSK6416_AIC23_DIGACT     Digital interface activation */   \
};   
     
void initMcbsp(void);//初始化Mcbsp
/*----------------------------------------------------------------------------*/
void main(){

  /* initialize the CSL library */
  CSL_init();

  /* initialize the input source data */
  ping_data=0x00000000;
  pong_data=0x80000000;
  
  /* Since these variables are the source of an EDMA transfer, we     */
  /* need to flush them out of the cache since we just wrote to them. */
  CACHE_flush(CACHE_L2,&ping_data,1);
  CACHE_flush(CACHE_L2,&pong_data,1);
        initMcbsp();               // 初始化 McBSP1 接收AD6620串行输出的数据
  
           
  /* Let's disable/clear related interrupts just in case they are pending */
  /* fram a previous run of the program.                                  */  
  IRQ_reset(IRQ_EVT_EDMAINT);
  EDMA_intDisable(TCCINTNUM);
  EDMA_intClear(TCCINTNUM);
  
  /* Although not required, let's clear all of the EDMA parameter RAM. */
  /* This makes it easier to view the RAM and see the changes as we    */
  /* configure it.                                                     */
  EDMA_clearPram(0x00000000);
   
  /* Lets open up the EDMA channel associated with timer #1. */
  hEdma = EDMA_open(EDMA_CHA_REVT0, EDMA_OPEN_RESET);

  /* We also need two EDMA reload parameter sets so let's allocate them */
  /* here. Notice the -1, this means allocate any availale tale.        */
  hEdmaPing = EDMA_allocTable(-1);
  hEdmaPong = EDMA_allocTable(-1);

  /* Let's copy the ping reload configuration structure to an */
  /* intermediate configuration structure.                    */
  cfgEdma = cfgEdmaPing;
  
  /* Let's initialize the link fields of the configuration structures */
  cfgEdmaPing.rld = EDMA_RLD_RMK(0,hEdmaPing);
  cfgEdmaPong.rld = EDMA_RLD_RMK(0,hEdmaPong);
  cfgEdma.rld     = EDMA_RLD_RMK(0,hEdmaPong);

  /* Now let's program up the EDMA channel with the configuration structure */
  EDMA_config(hEdma, &cfgEdma);   
  
  /* Let's also configure the reload parameter tables in the EDMA PRAM */
  /* with the values in the configuration structures.                  */
  EDMA_config(hEdmaPing, &cfgEdmaPing);
  EDMA_config(hEdmaPong, &cfgEdmaPong);   


  /* Enable the related interrupts */
  IRQ_enable(IRQ_EVT_EDMAINT);
  EDMA_intEnable(TCCINTNUM);        
  
  /* Enable the EDMA channel */
  EDMA_enableChannel(hEdma);   
  
}

/*----------------------------------------------------------------------------*/
void swiProcessFunc(int arg){

  int *inbuff;
  int x;

  if (pingpong){

    /* If pingpong is 0, then we own the ping input buffer */
    inbuff = ping;
    printf("Ping\n");
   
  }else{

    /* If pingpong is 1, then we own the pong input buffer */
    inbuff = pong;
    printf("Pong\n");

  }  

  /* Now let's process the input buffer, for simplicity, we'll */
  /* just copy it to the output buffer.                        */
  for (x=0; x<BUFF_SZ; x++) {
    outbuff[x] = inbuff[x];
  }

  /* If this example is enhanced to actually do something with the  */
  /* output buffer such as DMA it somewhere, you will want to flush */
  /* it out of the cache first.                                     */
  CACHE_flush(CACHE_L2,outbuff,BUFF_SZ);
  
  /* Since we're done processing the input buffer, clean it from cache, */
  /* this invalidates it from cache to ensure we read a fresh version   */
  /* the next time.                                                     */
  CACHE_clean(CACHE_L2,inbuff,BUFF_SZ);
}

/*----------------------------------------------------------------------------*/
void hwiEdmaIsr(int arg){
  
  /* Clear the pending interrupt from the EDMA interrupt pending register */
  EDMA_intClear(TCCINTNUM);
  EDMA_intEnable(TCCINTNUM);
  /* Perform ping-pong */
  pingpong = (pingpong + 1) & 1;

  /* Based on if we ping'ed or pong'ed, we need to set the EDMA channel */
  /* link address for the NEXT frame.                                   */
  
  if (pingpong){
    /* Currently doing pong so setup next frame for ping */                     
  
    /* Modify the input data source, this just simulates */
    /* the input data changing.                          */
    ping_data++;

    /* Rememer to flush this variable out of the cache */
    /* since it's the source of an EDMA transfer       */
    CACHE_flush(CACHE_L2,&ping_data,1);

    /* Now filling pong so set link to ping */
    EDMA_link(hEdma,hEdmaPing);
   
  }else{
    /* Currently doing ping so setup next frame for pong */                     
  
    /* Modify the output data source, this just simulates */
    /* the input data changing.                           */
    pong_data++;
   
    /* Rememer to flush this variable out of the cache */
    /* since it's the source of an EDMA transfer       */
    CACHE_flush(CACHE_L2,&pong_data,1);

    /* Now filling ping so set link to pong */
    EDMA_link(hEdma,hEdmaPong);
   
  }  

  /* Notify the app that we just ping-pong'ed */
  SWI_post(&swiProcess);
}

/*----------------------------------------------------------------------------*/
/*
*               initMcbsp()
*   使用前面定义的McBSP结构配置初始化McBSP  
*/
void initMcbsp()
{
    /* 打开McBSP1*/
     hMcbsp0 = MCBSP_open(MCBSP_DEV0, MCBSP_OPEN_RESET);
     
   
    AIC23_setParams(hMcbsp0,&config);  // Configure the codec
    /* 配置McBSP1 */
    MCBSP_config(hMcbsp0, &mcbspCfg0);
   
     /* 启动McBSP */
    MCBSP_start(hMcbsp0, MCBSP_XMIT_START | MCBSP_RCV_START |
        MCBSP_SRGR_START | MCBSP_SRGR_FRAMESYNC, 220);
   
}

/******************************************************************************\
* End of main.c
\******************************************************************************/
                                                                                


/*
*  Copyright 2003 by Texas Instruments Incorporated.
*  All rights reserved. Property of Texas Instruments Incorporated.
*  Restricted rights to use, duplicate or disclose this code are
*  granted through contract.
*  
*/

/*
*  ======== aic23.c ========
*
*  AIC23 codec driver implementation specific to the
*  Spectrum Digital DSK6713 board.
*/



#include <csl.h>
#include <csl_mcbsp.h>
#include "aic23.h"
static void aic23Rset(MCBSP_Handle hMcbsp, Uint16 regnum, Uint16 regval);


/*
*  ======== AIC23_setParams ========
*
*  This function takes a pointer to the object of type AIC23_Params,
*  and writes all 11 control words found in it to the codec. Prior
*  to that it initializes the codec if this is the first time the
*  function is ever called.
*  The 16-bit word is composed of register address in the upper 7 bits
*  and the 9-bit register value stored in the parameters structure.
*/
Void AIC23_setParams(MCBSP_Handle hMcbsp,AIC23_Params *params)
{
    Int i;
   
    /* Reset the AIC23 */
    aic23Rset(hMcbsp, AIC23_RESET, 0);
   
    /* Assign each register */
    for (i = 0; i < AIC23_NUMREGS; i++) {
        aic23Rset(hMcbsp, i, params->regs[i]);
    }
}



static Void aic23Rset(MCBSP_Handle hMcbsp, Uint16 regnum, Uint16 regval)
{
    regval &= 0x1ff;
   
    while (!MCBSP_xrdy(hMcbsp));
   
    /* Write 16 bit data value to DXR */
    MCBSP_write(hMcbsp, (regnum << 9) | regval);
   // while (MCBSP_xrdy(hMcbsp));
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2012-11-1 16:16:07 | 显示全部楼层
这程序太长了。

出0入0汤圆

 楼主| 发表于 2012-11-2 14:16:00 | 显示全部楼层
PSP2000 发表于 2012-11-1 16:16
这程序太长了。

这位大哥,有没有可用的程序,给发一个吧,我是刚学DSP,又是自学,糊里糊涂啊。

出0入0汤圆

发表于 2012-11-2 20:35:38 | 显示全部楼层
我也没有,不好意思哦

出0入0汤圆

发表于 2013-2-16 22:10:41 | 显示全部楼层
这位兄台,我也是正在自学DM642,可否交流交流?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-19 14:56

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表