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.
/*******************************************************************/ /* 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 */