|
各位大侠:
我做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周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|