Example #1
0
/**
 * \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);
}
Example #2
0
/* 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;
}