This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320C6472 connect with TMS320AIC3262 by McBSP i2s

Other Parts Discussed in Thread: TMS320C6472, BIOSLINUXMCSDK

Hi Raja,

Could you help to share the whole "McBSP as I2S " project with me ?

Or could you please help to complete the project? I have already copied the codes in the application note. The head files in the docment are missed.

I am using TMS320C6472 to connect with TMS320AIC3262 and need to use McBSP as I2S (C6472 used as slave mode for recording and as master mode for playback).

Thanks a lot.

I2S_TMS320C64X.c
/*******************************************************************/
/* mcbsp.c */
/*******************************************************************/
#include <mcbsp.h>
#include <dma.h>
#include <time.h>
#include <stdlib.h>
/* Definitions */
#define MEM_SRC 0x80000000
#define MEM_DST 0x80001000
/* Uncomment the following for C6000 as I2S slave */
//#define SLAVE
/* Global variables */
int RECV_done = 0;
int XMIT_done = 0;
int DMA_done[4] = {0, 0, 0, 0};
/* Prototypes */
extern void set_interrupts(void);
void config_serial(void);
void start_cs4226(void);


void start_sp_dma(void);
void
start_sp_dma(void)
{
unsigned int dma_pri_ctrl = 0;
unsigned int dma_sec_ctrl = 0;
unsigned int dma_src_addr = 0;
unsigned int dma_dst_addr = 0;
unsigned int dma_tcnt = 0;
unsigned int dma_index = 0;
/* Clear completion flag */
DMA_done[0] = 0;
/* Reset DMA Control Registers */
/* use DMA Ch0 to service McBSP */
dma_reset();
DMA_RSYNC_CLR(0);
DMA_WSYNC_CLR(0);
dma_reset();
/* Set up DMA Channel to perform a block transfer of */
/* XFER_SIZE elements */
/* from MEM_SRC to McBSP */
/* Set up DMA Primary Control Register */
LOAD_FIELD(&dma_pri_ctrl, DMA_RELOAD_GARC, DST_RELOAD,DST_RELOAD_SZ);
LOAD_FIELD(&dma_pri_ctrl, DMA_RELOAD_GARB, SRC_RELOAD,SRC_RELOAD_SZ);
LOAD_FIELD(&dma_pri_ctrl, DMA_DMA_PRI , PRI , 1 );
LOAD_FIELD(&dma_pri_ctrl, SEN_XEVT0 , WSYNC , WSYNC_SZ );
LOAD_FIELD(&dma_pri_ctrl, SEN_REVT0 , RSYNC , RSYNC_SZ );
LOAD_FIELD(&dma_pri_ctrl, DMA_SPLIT_GARA , SPLIT , SPLIT_SZ );
LOAD_FIELD(&dma_pri_ctrl, DMA_ESIZE32 , ESIZE , ESIZE_SZ );
LOAD_FIELD(&dma_pri_ctrl, DMA_ADDR_INDX, DST_DIR , DST_DIR_SZ );
LOAD_FIELD(&dma_pri_ctrl, DMA_ADDR_INDX, SRC_DIR , SRC_DIR_SZ );
SET_BIT(&dma_pri_ctrl,EMOD); /* Halt DMA with emu halt */
SET_BIT(&dma_pri_ctrl,TCINT); /* Allow Ch to interrupt CPU */
/* Set up DMA Secondary Control Register */
LOAD_FIELD(&dma_sec_ctrl, DMAC_BLOCK_COND, DMAC_EN , DMAC_EN_SZ );
SET_BIT(&dma_sec_ctrl, BLOCK_IE);
/* Set up DMA Tranfer Count Register */
LOAD_FIELD(&dma_tcnt, 0x100 , FRAME_COUNT , FRAME_COUNT_SZ );
LOAD_FIELD(&dma_tcnt, 2 , ELEMENT_COUNT, ELEMENT_COUNT_SZ);
/* Set up DMA Index Register */
LOAD_FIELD(&dma_index, -0x7FC , FRAME_INDEX , FRAME_INDEX_SZ );
LOAD_FIELD(&dma_index, 0x800 , ELEMENT_INDEX, ELEMENT_INDEX_SZ);
/* Set up Source and Destination Address Registers */
dma_src_addr = (unsigned int)MEM_SRC;

dma_dst_addr = (unsigned int)MEM_DST;
DMA_GADDR_A = (unsigned int)MCBSP_DRR_ADDR(0);
DMA_GADDR_B = (unsigned int)MEM_SRC;
DMA_GADDR_C = (unsigned int)MEM_DST;
DMA_GCR_A = dma_tcnt;
DMA_GNDX_A = dma_index;
/* Store DMA Control registers */
dma_init(0,
dma_pri_ctrl,
dma_sec_ctrl,
dma_src_addr,
dma_dst_addr,
dma_tcnt);
/* Start DMA Transfer */
DMA_AUTO_START(0);
DMA_RSYNC_CLR(0);
DMA_WSYNC_CLR(0);
} /* end start_sp_dma */
void
config_serial(void)
{
unsigned int spcr = 0;
unsigned int rcr = 0;
unsigned int xcr = 0;
unsigned int srgr = 0;
unsigned int mcr = 0;
unsigned int rcer = 0;
unsigned int xcer = 0;
unsigned int pcr = 0;
/* Set up Pin Control Register */
#ifndef SLAVE
LOAD_FIELD(&pcr, FSYNC_MODE_INT , FSXM , 1);
LOAD_FIELD(&pcr, FSYNC_MODE_INT , FSRM , 1);
LOAD_FIELD(&pcr, CLK_MODE_INT , CLKXM, 1);
LOAD_FIELD(&pcr, CLK_MODE_INT , CLKRM, 1);
#else
LOAD_FIELD(&pcr, FSYNC_MODE_EXT , FSXM , 1);
LOAD_FIELD(&pcr, FSYNC_MODE_EXT , FSRM , 1);
LOAD_FIELD(&pcr, CLK_MODE_EXT , CLKXM, 1);
LOAD_FIELD(&pcr, CLK_MODE_EXT , CLKRM, 1);
#endif
LOAD_FIELD(&pcr, FSYNC_POL_HIGH , FSXP , 1);
LOAD_FIELD(&pcr, FSYNC_POL_HIGH , FSRP , 1);
LOAD_FIELD(&pcr, CLKX_POL_RISING , CLKXP, 1);
LOAD_FIELD(&pcr, CLKR_POL_FALLING, CLKRP, 1);
/* Set up Receive Control Register */
LOAD_FIELD(&rcr, DUAL_PHASE , RPHASE, 1);
LOAD_FIELD(&rcr, FRAME_IGNORE , RFIG , 1);
LOAD_FIELD(&rcr, DATA_DELAY1 , RDATDLY, RDATDLY_SZ);
LOAD_FIELD(&rcr, 0 , RFRLEN1, RFRLEN1_SZ);
LOAD_FIELD(&rcr, 0 , RFRLEN2, RFRLEN2_SZ);
LOAD_FIELD(&rcr, WORD_LENGTH_32 , RWDLEN1, RWDLEN1_SZ);
LOAD_FIELD(&rcr, WORD_LENGTH_32 , RWDLEN2, RWDLEN2_SZ);
LOAD_FIELD(&rcr, NO_COMPAND_MSB_1ST , RCOMPAND, RCOMPAND_SZ);
/* Set up Transmit Control Register */
LOAD_FIELD(&xcr, DUAL_PHASE , XPHASE, 1);
LOAD_FIELD(&xcr, FRAME_IGNORE , XFIG , 1);
LOAD_FIELD(&xcr, DATA_DELAY1 , XDATDLY, XDATDLY_SZ);
LOAD_FIELD(&xcr, 0 , XFRLEN1, XFRLEN1_SZ);
LOAD_FIELD(&xcr, 0 , XFRLEN2, XFRLEN2_SZ);
LOAD_FIELD(&xcr, WORD_LENGTH_32 , XWDLEN1, XWDLEN1_SZ);
LOAD_FIELD(&xcr, WORD_LENGTH_32 , XWDLEN2, XWDLEN2_SZ);
LOAD_FIELD(&xcr, NO_COMPAND_MSB_1ST, XCOMPAND, XCOMPAND_SZ);
/* Set up Sample Rate Generator Register */
#ifndef SLAVE
SET_BIT(&srgr, CLKSM); /* CLKG derived from CPU clock*/
LOAD_FIELD(&srgr, FSX_FSG, FSGM, 1);
LOAD_FIELD(&srgr, 70, CLKGDV, CLKGDV_SZ);
LOAD_FIELD(&srgr, 63, FPER, FPER_SZ);
LOAD_FIELD(&srgr, 31, FWID, FWID_SZ);
#endif
/* Store McBSP 0 registers */
mcbsp_init(0, spcr, rcr, xcr, srgr, mcr, rcer, xcer, pcr);
/* Bring McBSP out of reset */
MCBSP_SAMPLE_RATE_ENABLE(0); /* Start Sample Rate Generator */
MCBSP_FRAME_SYNC_ENABLE(0); /* Enable Frame Sync pulse */
} /* End config_serial */
void start_cs4226(void)
{
unsigned int spcr = 0;
unsigned int rcr = 0;
unsigned int xcr = 0;
unsigned int srgr = 0;
unsigned int mcr = 0;
unsigned int rcer = 0;
unsigned int xcer = 0;
unsigned int pcr = 0;
clock_t ctemp;
/* Set up Pin Control Register */
LOAD_FIELD(&pcr, FSYNC_MODE_INT , FSXM , 1);
LOAD_FIELD(&pcr, FSYNC_MODE_INT , FSRM , 1);
LOAD_FIELD(&pcr, CLK_MODE_INT , CLKXM, 1);
LOAD_FIELD(&pcr, CLK_MODE_INT , CLKRM, 1);
LOAD_FIELD(&pcr, FSYNC_POL_LOW , FSXP , 1);
LOAD_FIELD(&pcr, FSYNC_POL_LOW , FSRP , 1);
LOAD_FIELD(&pcr, CLKX_POL_FALLING , CLKXP, 1);
LOAD_FIELD(&pcr, CLKR_POL_RISING, CLKRP, 1);
/* Set up Receive Control Register */
LOAD_FIELD(&rcr, SINGLE_PHASE , RPHASE, 1);
LOAD_FIELD(&rcr, FRAME_IGNORE , RFIG , 1);
LOAD_FIELD(&rcr, DATA_DELAY1 , RDATDLY, RDATDLY_SZ);
LOAD_FIELD(&rcr, 0 , RFRLEN1, RFRLEN1_SZ);
LOAD_FIELD(&rcr, WORD_LENGTH_24 , RWDLEN1, RWDLEN1_SZ);
LOAD_FIELD(&rcr, NO_COMPAND_MSB_1ST , RCOMPAND, RCOMPAND_SZ);
/* Set up Transmit Control Register */
LOAD_FIELD(&xcr, SINGLE_PHASE , XPHASE, 1);
LOAD_FIELD(&xcr, FRAME_IGNORE , XFIG , 1);
LOAD_FIELD(&xcr, DATA_DELAY1 , XDATDLY, XDATDLY_SZ);
LOAD_FIELD(&xcr, 0 , XFRLEN1, XFRLEN1_SZ);
LOAD_FIELD(&xcr, WORD_LENGTH_24 , XWDLEN1, XWDLEN1_SZ);
LOAD_FIELD(&xcr, NO_COMPAND_MSB_1ST, XCOMPAND, XCOMPAND_SZ);
/* Set up Serial Port Control Register */
LOAD_FIELD(&spcr, INTM_RDY , XINTM, XINTM_SZ );
LOAD_FIELD(&spcr, INTM_RDY , RINTM, RINTM_SZ );
LOAD_FIELD(&spcr, 2, CLKSTP, 1);
/* Set up Sample Rate Generator Register */
SET_BIT(&srgr, CLKSM); /* CLKG derived from CPU clock*/
LOAD_FIELD(&srgr, FSX_DXR_TO_XSR, FSGM, 1);
LOAD_FIELD(&srgr, 70, CLKGDV, CLKGDV_SZ);
/* Store McBSP 1 registers */
mcbsp_init(1, spcr, rcr, xcr, srgr, mcr, rcer, xcer, pcr);
/* Bring McBSP out of reset */
MCBSP_SAMPLE_RATE_ENABLE(1); /* Start Sample Rate Generator */
MCBSP_FRAME_SYNC_ENABLE(1); /* Enable Frame Sync pulse */
MCBSP_ENABLE(1, MCBSP_RX); /* Bring Receive out of reset */
MCBSP_ENABLE(1, MCBSP_TX); /* Bring Transmit out of reset */
/* Program CS4226 registers */
XMIT_done=0; /* wait for McBSP to initialize */
while(!XMIT_done);
#ifndef SLAVE
XMIT_done=0; /* Clock is PLL driven by LRCK at 1 Fs, CLKOUT = 1 Fs */
MCBSP1_DXR = 0x200162;
#else
XMIT_done=0; /* Clock is ext oscillator, CLKOUT = 1 Fs */
MCBSP1_DXR = 0x200160;
#endif
while(!XMIT_done);
XMIT_done=0; /* Mute all DACs but 1 & 2 (stereo pair 1) */
MCBSP1_DXR = 0x2003FC;
while(!XMIT_done);
XMIT_done=0; /* No DAC attenuation */
MCBSP1_DXR = 0x200400;
while(!XMIT_done);
XMIT_done=0; /* No DAC attenuation */
MCBSP1_DXR = 0x200500;
while(!XMIT_done);
XMIT_done=0; /* No DAC attenuation */
MCBSP1_DXR = 0x200600;
while(!XMIT_done);
XMIT_done=0; /* No DAC attenuation */
MCBSP1_DXR = 0x200700;
while(!XMIT_done);
XMIT_done=0; /* No DAC attenuation */
MCBSP1_DXR = 0x200800;
while(!XMIT_done);
XMIT_done=0; /* No DAC attenuation */
MCBSP1_DXR = 0x200900;
while(!XMIT_done);
#ifndef SLAVE
XMIT_done=0; /* C4226 is slave, I2S format, 64 bit clocks per Fs */
MCBSP1_DXR = 0x200ECC;
#else
XMIT_done=0; /* C4226 is Master, I2S format, 64 bit clocks per Fs */
MCBSP1_DXR = 0x200EEC;
#endif
while(!XMIT_done);
XMIT_done=0; /* Pull device out of reset */
MCBSP1_DXR = 0x200200;
while(!XMIT_done);
/* Wait 90ms for PLL to lock onto the LRCK (FSX) */
ctemp=clock();
while(clock() < ctemp + 90);
} /* End start_cs4226 */
/* McBSP verification test code. */
void
main (void)
{
int i;
set_interrupts();
start_sp_dma();
config_serial();
start_cs4226();
MCBSP_ENABLE(0, MCBSP_RX); /* Bring Receive out of reset */
MCBSP_ENABLE(0, MCBSP_TX); /* Bring Transmit out of reset */
while(1){
/* Set up DMA reload registers for the next block */
DMA_GADDR_B = (unsigned int)MEM_SRC + 0x400;
DMA_GADDR_C = (unsigned int)MEM_DST + 0x400;
/* Wait for current block to finish */
while(!DMA_done[0]);
DMA_done[0]=0;
/* Transfer the recently completed block from the input buffer */
/* to the output buffer. Here is where any algorithms to do DSP*/
/* on the data would go. */
for ( i = 0; i < 0x100; i++){
*(int *) (MEM_SRC + 4*i) =
*(int *) (MEM_DST + 4*i);
*(int *) (MEM_SRC + 4*i + 0x800) =
*(int *) (MEM_DST + 4*i + 0x800);
}
/* Set up DMA reload registers for the next block */
DMA_GADDR_B = (unsigned int)MEM_SRC;
DMA_GADDR_C = (unsigned int)MEM_DST;
/* Wait for current block to finish */
while(!DMA_done[0]);
DMA_done[0]=0;
/* Transfer the recently completed block from the input buffer */
/* to the output buffer. Here is where any algorithms to do DSP*/
/* on the data would go. */
for ( i = 0; i < 0x100; i++){
*(int *) (MEM_SRC + 4*i + 0x400) =
*(int *) (MEM_DST + 4*i + 0x400);
*(int *) (MEM_SRC + 4*i + 0xC00) =
*(int *) (MEM_DST + 4*i + 0xC00);
}
}
} /* end main */
/*******************************************************************/
/* dma_int.c */
/*******************************************************************/
#include <intr.h>
#include <dma.h>
/* Global variables */
extern int DMA_done[4];
extern int RECV_done;
extern int XMIT_done;
/* Prototypes */
interrupt void DMA_Ch0_ISR(void);
interrupt void RINT_ISR(void);
interrupt void XINT_ISR(void);
void set_interrupts(void);
/* DMA Ch0 ISR used to clear block condition and flag when the */
/* transfer has completed. */
interrupt void
DMA_Ch0_ISR(void)
{
	unsigned int sec_ctrl = 0x50000;
sec_ctrl = REG_READ(DMA0_SECONDARY_CTRL_ADDR);
if (GET_BIT(&sec_ctrl, BLOCK_COND)){
DMA_done[0] = 1;
RESET_BIT(&sec_ctrl, BLOCK_COND);
}
REG_WRITE(DMA0_SECONDARY_CTRL_ADDR, sec_ctrl);
} /* End DMA_Ch0_ISR */
interrupt void
XINT_ISR(void)
{
XMIT_done=1;
}
interrupt void
RINT_ISR(void)
{
RECV_done=1;
}
/* Routine to enable DMA and Timer interrupt service routines */
void
set_interrupts(void)
{
intr_init();
intr_map(CPU_INT8, ISN_DMA_INT0);
intr_hook(DMA_Ch0_ISR, CPU_INT8);
intr_map(CPU_INT11, ISN_XINT1);
intr_hook(XINT_ISR, CPU_INT11);
intr_map(CPU_INT12, ISN_RINT1);
intr_hook(RINT_ISR, CPU_INT12);
INTR_GLOBAL_ENABLE();
INTR_ENABLE(CPU_INT_NMI);
INTR_ENABLE(CPU_INT8);
INTR_ENABLE(CPU_INT11);
INTR_ENABLE(CPU_INT12);
} /* End set_interrupts */