/** * \brief Routine to modify address for DMA offset * * This function modifies the source/destination address specified by the * application according to the requirement of DMA * * \param address [IN] Address given by application * * \return modAddr - modified address */ Uint32 DMA_AdjustAddrOffset(Uint32 address) { Uint32 modAddr; /* Call DDC API for modifying the address */ modAddr = DDC_DMAAdjustAddrOffset(address); return(modAddr); }
/* Initializes I2S and associated DMA channels for Playback and Record */ Int16 i2sInit( I2sInitPrms *pI2sInitPrms ) { PSP_I2SOpMode opMode; PSP_I2SConfig i2sTxConfig; PSP_DMAConfig dmaTxConfig; PSP_I2SConfig i2sRxConfig; PSP_DMAConfig dmaRxConfig; if (pI2sInitPrms->enablePlayback == TRUE) { /* Initialize I2S instance for Playback */ i2sTxConfig.loopBack = PSP_I2S_LOOPBACK_DISABLE; i2sTxConfig.i2sMode = PSP_I2S_SLAVE; i2sTxConfig.word_len = PSP_I2S_WORDLEN_16; i2sTxConfig.signext = PSP_I2S_SIGNEXT_ENABLE; i2sTxConfig.datatype = PSP_I2S_MONO_DISABLE; i2sTxConfig.fsync_pol = PSP_I2S_FSPOL_LOW; i2sTxConfig.clk_pol = PSP_I2S_FALLING_EDGE; i2sTxConfig.datadelay = PSP_I2S_DATADELAY_ONEBIT; i2sTxConfig.dataformat = PSP_I2S_DATAFORMAT_LJUST; i2sTxConfig.fsdiv = PSP_I2S_FSDIV32; i2sTxConfig.clkdiv = PSP_I2S_CLKDIV2; if (pI2sInitPrms->sampleBySamplePb == TRUE) { i2sTxConfig.datapack = PSP_I2S_DATAPACK_DISABLE; opMode = PSP_I2S_INTERRUPT; /* change from PSP_DMA_INTERRUPT to PSP_I2S_INTERRUPT SampleBySample */ } else { i2sTxConfig.datapack = PSP_I2S_DATAPACK_ENABLE; opMode = PSP_DMA_INTERRUPT; } i2sHandleTx = I2S_INIT(pI2sInitPrms->i2sPb, PSP_I2S_TRANSMIT, PSP_I2S_CHAN_STEREO, opMode, &i2sTxConfig, NULL); if (i2sHandleTx == NULL) { return I2SSAMPLE_I2SINIT_PB_FAIL; } if (pI2sInitPrms->sampleBySamplePb == FALSE) { /* Initialize DMA channels for Playback */ dmaTxConfig.pingPongMode = pI2sInitPrms->enableDmaPingPongPb; dmaTxConfig.autoMode = (pI2sInitPrms->enableDmaPingPongPb == FALSE) ? PSP_DMA_AUTORELOAD_DISABLE : PSP_DMA_AUTORELOAD_ENABLE; dmaTxConfig.burstLen = PSP_DMA_TXBURST_1WORD; dmaTxConfig.chanDir = PSP_DMA_WRITE; dmaTxConfig.trigger = PSP_DMA_EVENT_TRIGGER; dmaTxConfig.trfType = PSP_DMA_TRANSFER_IO_MEMORY; dmaTxConfig.dataLen = (pI2sInitPrms->enableDmaPingPongPb == FALSE) ? 2*MAX_I2S_TXBUFF_SZ : 2*2*MAX_I2S_TXBUFF_SZ; dmaTxConfig.srcAddr = (Uint32)pI2sInitPrms->pingI2sTxLeftBuf; //dmaTxConfig.callback = I2S_DmaTxCallBack; switch (pI2sInitPrms->i2sPb) { case PSP_I2S_0: dmaTxConfig.dmaEvt = PSP_DMA_EVT_I2S0_TX; dmaTxConfig.destAddr = (Uint32)I2S0_I2STXLT0; break; case PSP_I2S_1: dmaTxConfig.dmaEvt = PSP_DMA_EVT_I2S1_TX; dmaTxConfig.destAddr = (Uint32)I2S1_I2STXLT0; break; case PSP_I2S_2: dmaTxConfig.dmaEvt = PSP_DMA_EVT_I2S2_TX; dmaTxConfig.destAddr = (Uint32)I2S2_I2STXLT0; break; case PSP_I2S_3: dmaTxConfig.dmaEvt = PSP_DMA_EVT_I2S3_TX; dmaTxConfig.destAddr = (Uint32)I2S3_I2STXLT0; break; default: return I2SSAMPLE_INV_PRMS; } /* Request and configure a DMA channel for left channel data */ hDmaTxLeft = I2S_DMA_INIT(i2sHandleTx, &dmaTxConfig); if (hDmaTxLeft == NULL) { return I2SSAMPLE_DMAINIT_PB_FAIL; } /* Request and configure a DMA channel for right channel data */ dmaTxConfig.srcAddr = (Uint32)pI2sInitPrms->pingI2sTxRightBuf; switch (pI2sInitPrms->i2sPb) { case PSP_I2S_0: dmaTxConfig.destAddr = (Uint32)I2S0_I2STXRT0; break; case PSP_I2S_1: dmaTxConfig.destAddr = (Uint32)I2S1_I2STXRT0; break; case PSP_I2S_2: dmaTxConfig.destAddr = (Uint32)I2S2_I2STXRT0; break; case PSP_I2S_3: dmaTxConfig.destAddr = (Uint32)I2S3_I2STXRT0; break; default: return I2SSAMPLE_INV_PRMS; } /* Request and configure a DMA channel for right data */ hDmaTxRight = I2S_DMA_INIT(i2sHandleTx, &dmaTxConfig); if (hDmaTxRight == NULL) { return I2SSAMPLE_DMAINIT_PB_FAIL; } if (pI2sInitPrms->enableDmaPingPongPb == FALSE) { gi2sTxLeftBuf = DDC_DMAAdjustAddrOffset((Uint32)pI2sInitPrms->pingI2sTxLeftBuf); gi2sTxRightBuf = DDC_DMAAdjustAddrOffset((Uint32)pI2sInitPrms->pingI2sTxRightBuf); gi2sNextTxLeftBuf = DDC_DMAAdjustAddrOffset((Uint32)pI2sInitPrms->pongI2sTxLeftBuf); gi2sNextTxRightBuf = DDC_DMAAdjustAddrOffset((Uint32)pI2sInitPrms->pongI2sTxRightBuf); gZeroBuf = DDC_DMAAdjustAddrOffset((Uint32)pI2sInitPrms->zeroBuf); } /* Zero buffers */ zeroi2sBuf(pI2sInitPrms->enableStereoPb, pI2sInitPrms->enableDmaPingPongPb, pI2sInitPrms->pingI2sTxLeftBuf, pI2sInitPrms->pingI2sTxRightBuf, pI2sInitPrms->pongI2sTxLeftBuf, pI2sInitPrms->pongI2sTxRightBuf, pI2sInitPrms->zeroBuf); } } if (pI2sInitPrms->enableRecord == TRUE) { /* Initialize I2S instance for Record */ i2sRxConfig.loopBack = PSP_I2S_LOOPBACK_DISABLE; i2sRxConfig.i2sMode = PSP_I2S_SLAVE; i2sRxConfig.word_len = PSP_I2S_WORDLEN_16; i2sRxConfig.signext = PSP_I2S_SIGNEXT_ENABLE; i2sRxConfig.datatype = PSP_I2S_MONO_DISABLE; i2sRxConfig.fsync_pol = PSP_I2S_FSPOL_LOW; i2sRxConfig.clk_pol = PSP_I2S_FALLING_EDGE; i2sRxConfig.datadelay = PSP_I2S_DATADELAY_ONEBIT; i2sRxConfig.dataformat = PSP_I2S_DATAFORMAT_LJUST; i2sRxConfig.fsdiv = PSP_I2S_FSDIV32; i2sRxConfig.clkdiv = PSP_I2S_CLKDIV2; /* If datapack disabled on Tx, we need it disabled on Rx => we get 2 words per DMA transfer so the DMA buffers have to be twice as big */ i2sRxConfig.datapack = (pI2sInitPrms->sampleBySamplePb == TRUE) ? PSP_I2S_DATAPACK_DISABLE : PSP_I2S_DATAPACK_ENABLE; if (pI2sInitPrms->sampleBySampleRec == TRUE) { opMode = PSP_I2S_INTERRUPT; } else { opMode = PSP_DMA_INTERRUPT; } i2sHandleRx = I2S_INIT(pI2sInitPrms->i2sRec, PSP_I2S_RECEIVE, PSP_I2S_CHAN_STEREO, opMode, &i2sRxConfig, NULL); if (i2sHandleRx == NULL) { return I2SSAMPLE_I2SINIT_REC_FAIL; } if (pI2sInitPrms->sampleBySampleRec == FALSE) { /* Initialize DMA channels for Record */ dmaRxConfig.pingPongMode = pI2sInitPrms->enableDmaPingPongRec; dmaRxConfig.autoMode = (pI2sInitPrms->enableDmaPingPongRec == FALSE) ? PSP_DMA_AUTORELOAD_DISABLE : PSP_DMA_AUTORELOAD_ENABLE; dmaRxConfig.burstLen = PSP_DMA_TXBURST_1WORD; dmaRxConfig.chanDir = PSP_DMA_READ; dmaRxConfig.trigger = PSP_DMA_EVENT_TRIGGER; dmaRxConfig.trfType = PSP_DMA_TRANSFER_IO_MEMORY; dmaRxConfig.dataLen = (pI2sInitPrms->enableDmaPingPongPb == FALSE) ? (2*I2S_RXBUFF_SZ) : 2*(2*I2S_RXBUFF_SZ); dmaRxConfig.destAddr = (Uint32)pI2sInitPrms->pingI2sRxLeftBuf; dmaRxConfig.callback = I2S_DmaRxLChCallBack; switch (pI2sInitPrms->i2sRec) { case PSP_I2S_0: dmaRxConfig.dmaEvt = PSP_DMA_EVT_I2S0_RX; dmaRxConfig.srcAddr = (Uint32)I2S0_I2SRXLT0; break; case PSP_I2S_1: dmaRxConfig.dmaEvt = PSP_DMA_EVT_I2S1_RX; dmaRxConfig.srcAddr = (Uint32)I2S1_I2SRXLT0; break; case PSP_I2S_2: dmaRxConfig.dmaEvt = PSP_DMA_EVT_I2S2_RX; dmaRxConfig.srcAddr = (Uint32)I2S2_I2SRXLT0; break; case PSP_I2S_3: dmaRxConfig.dmaEvt = PSP_DMA_EVT_I2S3_RX; dmaRxConfig.srcAddr = (Uint32)I2S3_I2SRXLT0; break; default: return I2SSAMPLE_INV_PRMS; } /* Request and configure a DMA channel for left channel data */ hDmaRxLeft = I2S_DMA_INIT(i2sHandleRx, &dmaRxConfig); if (hDmaRxLeft == NULL) { return I2SSAMPLE_DMAINIT_REC_FAIL; } /* Request and configure a DMA channel for right channel data */ switch (pI2sInitPrms->i2sPb) { case PSP_I2S_0: dmaRxConfig.srcAddr = (Uint32)I2S0_I2SRXRT0; break; case PSP_I2S_1: dmaRxConfig.srcAddr = (Uint32)I2S1_I2SRXRT0; break; case PSP_I2S_2: dmaRxConfig.srcAddr = (Uint32)I2S2_I2SRXRT0; break; case PSP_I2S_3: dmaRxConfig.srcAddr = (Uint32)I2S3_I2SRXRT0; break; default: return I2SSAMPLE_INV_PRMS; } dmaRxConfig.destAddr = (Uint32)pI2sInitPrms->pingI2sRxRightBuf; dmaRxConfig.callback = I2S_DmaRxRChCallBack; /* Request and configure a DMA channel for right data */ hDmaRxRight = I2S_DMA_INIT(i2sHandleRx, &dmaRxConfig); if (hDmaRxRight == NULL) { return I2SSAMPLE_DMAINIT_REC_FAIL; } if (pI2sInitPrms->enableDmaPingPongPb == FALSE) { gi2sRxLeftBuf = DDC_DMAAdjustAddrOffset((Uint32)pI2sInitPrms->pingI2sRxLeftBuf); gi2sRxRightBuf = DDC_DMAAdjustAddrOffset((Uint32)pI2sInitPrms->pingI2sRxRightBuf); gi2sNextRxLeftBuf = DDC_DMAAdjustAddrOffset((Uint32)pI2sInitPrms->pongI2sRxLeftBuf); gi2sNextRxRightBuf = DDC_DMAAdjustAddrOffset((Uint32)pI2sInitPrms->pongI2sRxRightBuf); } } } return I2SSAMPLE_SOK; }