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.

66AK2G02: The McASP I/O Control

Part Number: 66AK2G02
Other Parts Discussed in Thread: DIR9001, AUDK2G

Sometimes Audio noise was confirmed on the evaluation board (K2G Audio Daughter Card + EVMK2G).

As shown in the attached file, the software is modified so that a signal is input to Digital audio IN of  EVMK2G Audio Daughter Card and output from DAC_OUT0.

The I2S signal is input to McASP2 and the signal is output from McASP0.

Separate clocks are used for McASP0 and McASP2.

・McASP2(from DIR9001) use ACLKR input clock.

ACLKRCTL = 0x0080  AHCLKRCTL = 0x0000

・McASP0(to DAC) use internal clock

ACLKXCTL = 0x00A7

Why is audio noise occurring? Is there problem about the McASP use way ?

  • Could you clarify, what software are you using with this setup and what is the sampling rate used with this playback.

    I would recommend that you look at the AUDK2G example in our Processor SDK RTOS that does a 8 channel audio loop back.

    Source Code: pdk_k2g_1_0_15\packages\ti\addon\aud\test

    Here is the MCASP configuration file from that example:

    7633.mcasp_cfg.c
    /*
     * Copyright (c) 2015, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    
    /**
     * \file      mcasp_config.c
     *
     * \brief     Configures McASP module
     *
     */
    
    #include "mcasp_cfg.h"
    
    #include <ti/drv/uart/UART.h>
    #include <ti/drv/uart/UART_stdio.h>
    
    /* Frame index for Rx and Tx buffers */
    uint8_t rxFrameIndex = 1;
    uint8_t txFrameIndex = 1;
    uint32_t gtxFrameIndexCount = 0;
    uint32_t grxFrameIndexCount = 0;
    
    /* Flags for counting Rx and Tx interrupts */
    volatile uint32_t rxFlag = 0;
    volatile uint32_t txFlag = 0;
    
    /* Semaphore handle for Tx and Rx */
    Semaphore_Handle semR;
    Semaphore_Handle semT;
    Semaphore_Params params;
    
    /* McASP device handles */
    Ptr hMcaspDevTx;
    Ptr hMcaspDevRx;
    
    /* McASP channel handles */
    Ptr hMcaspTxChan;
    Ptr hMcaspRxChan;
    
    /* McASP channel parameters */
    Mcasp_Params mcaspTxParams;
    Mcasp_Params mcaspRxParams;
    
    /* McASP Callback function argument */
    uint32_t txChanMode;
    uint32_t rxChanMode;
    uint32_t mcaspRxChanArg = 1;
    uint32_t mcaspTxChanArg = 2;
    
    /* McASP Tx and Rx frame buffers */
    MCASP_Packet rxFrame[NUM_BUFS];
    MCASP_Packet txFrame[NUM_BUFS];
    
    /* McASP Tx and Rx frame buffer pointers */
    Ptr txBuf[NUM_BUFS];
    Ptr rxBuf[NUM_BUFS];
    
    /* Error flag */
    uint32_t gblErrFlag = 0;
    Error_Block eb;
    
    /* Handle to heap object */
    extern HeapMem_Handle heapHandle;
    
    /* Mcasp IOM function object */
    extern IOM_Fxns Mcasp_IOMFXNS;
    
    /* External function declarations */
    void McaspDevice_init(void);
    void GblErr(int arg);
    signed char*  getGlobalAddr(signed char* addr);
    void aud_write(const char *fmt, ... );
    
    #define TX_FIFO_EVENT_DMA_RATIO  2
    #define RX_FIFO_EVENT_DMA_RATIO  2
    /* McASP HW setup for receive */
    Mcasp_HwSetupData mcaspRcvSetup = {
            /* .rmask    = */ 0xFFFFFFFF, /* 16 bits are to be used     */
            /* .rfmt     = */ 0x000180F2, /*
                                           * 0 bit delay from framesync
                                           * MSB first
                                           * No extra bit padding
                                           * Padding bit (ignore)
                                           * slot Size is 32
                                           * Reads from DMA port
                                           * NO rotation
                                           */
            /* .afsrctl  = */ 0X00000112, /* I2S mode - 2 slot TDM
                                           * Frame sync is one word
                                           * Internally generated frame sync
                                           * Rising edge is start of frame
                                           */
            /* .rtdm     = */ 0x00000003, /* slot 1 and 2 are active (I2S)        */
            /* .rintctl  = */ 0x00000000, /* sync error and overrun error         */
            /* .rstat    = */ 0x000001FF, /* reset any existing status bits       */
            /* .revtctl  = */ 0x00000000, /* DMA request is enabled               */
            {
                 /* .aclkrctl  = */ 0x000000A7,
                 /* .ahclkrctl = */ 0x0000C000,
                 /* .rclkchk   = */ 0x00000000
            }
    };
    
    /* McASP HW setup for transmit */
    Mcasp_HwSetupData mcaspXmtSetup = {
            /* .xmask    = */ 0xFFFFFFFF, /* 16 bits are to be used     */
            /* .xfmt     = */ 0x000180F6, /*
                                           * 0 bit delay from framesync
                                           * MSB first
                                           * No extra bit padding
                                           * Padding bit (ignore)
                                           * slot Size is 32
                                           * Reads from DMA port
                                           * NO rotation
                                           */
            /* .afsxctl  = */ 0x00000112, /* I2S mode - 2 slot TDM
                                           * Frame sync is one word
                                           * Rising edge is start of frame
                                           * Internally generated frame sync
                                           */
            /* .xtdm     = */ 0x00000003, /* slot 1 and 2 are active (I2S)               */
            /* .xintctl  = */ 0x00000000, /* sync error,overrun error,clK error   */
            /* .xstat    = */ 0x000001FF, /* reset any existing status bits       */
            /* .xevtctl  = */ 0x00000000, /* DMA request is enabled or disabled   */
            {
                 /* .aclkxctl  = */ 0X000000A7,
                 /* .ahclkxctl = */ 0x0000C000,
                 /* .xclkchk   = */ 0x00000000
            },
    
    };
    
    /* McAsp channel parameters for receive                      */
    Mcasp_ChanParams  mcaspRxChanParam =
    {
    	0x0004,                    /* number of serializers      */
    	{Mcasp_SerializerNum_0,
    	 Mcasp_SerializerNum_1,
    	 Mcasp_SerializerNum_2,
    	 Mcasp_SerializerNum_3 }, /* serializer index           */
    	&mcaspRcvSetup,
    	TRUE,
    	Mcasp_OpMode_TDM,          /* Mode (TDM/DIT)             */
    	Mcasp_WordLength_32,
    	NULL,
    	0,
    	NULL,
    	GblErr,
    	2,                        /* number of TDM channels      */
    	Mcasp_BufferFormat_MULTISER_MULTISLOT_SEMI_INTERLEAVED_1,
    	TRUE,
    	RX_FIFO_EVENT_DMA_RATIO,
    	TRUE,
    	Mcasp_WordBitsSelect_LSB
    };
    
    /* McAsp channel parameters for transmit - DAC0              */
    Mcasp_ChanParams  mcaspTx0ChanParam =
    {
    	0x0004,                   /* number of serializers       */
    	{Mcasp_SerializerNum_0,
    	 Mcasp_SerializerNum_1,
    	 Mcasp_SerializerNum_2,
    	 Mcasp_SerializerNum_3 }, /* serializer index for DAC0    */
    	&mcaspXmtSetup,
    	TRUE,
    	Mcasp_OpMode_TDM,
    	Mcasp_WordLength_32,      /* word width                  */
    	NULL,
    	0,
    	NULL,
    	GblErr,
    	2,                        /* number of TDM channels      */
    	Mcasp_BufferFormat_MULTISER_MULTISLOT_SEMI_INTERLEAVED_1,
    	TRUE,
    	TX_FIFO_EVENT_DMA_RATIO,
    	TRUE,
    	Mcasp_WordBitsSelect_LSB
    };
    
    /* McAsp channel parameters for transmit - DAC1              */
    Mcasp_ChanParams  mcaspTx1ChanParam =
    {
    	0x0004,                   /* number of serializers       */
    	{Mcasp_SerializerNum_4,
    	 Mcasp_SerializerNum_5,
    	 Mcasp_SerializerNum_6,
    	 Mcasp_SerializerNum_7 }, /* serializer index for DAC0    */
    	&mcaspXmtSetup,
    	TRUE,
    	Mcasp_OpMode_TDM,
    	Mcasp_WordLength_32,      /* word width                  */
    	NULL,
    	0,
    	NULL,
    	GblErr,
    	2,                        /* number of TDM channels      */
    	Mcasp_BufferFormat_MULTISER_MULTISLOT_SEMI_INTERLEAVED_1,
    	TRUE,
    	TX_FIFO_EVENT_DMA_RATIO,
    	TRUE,
    	Mcasp_WordBitsSelect_LSB
    };
    
    /* Handle to eDMA */
    extern EDMA3_DRV_Handle hEdma0;
    extern EDMA3_DRV_Handle hEdma1;
    
    extern uint32_t sineData[];
    extern uint32_t sineData_4ch[];
    
    /**
     *  \brief    Function called by McASP driver in case of error
     *
     *  \return    None
     */
    void GblErr(int arg)
    {
    	gblErrFlag = 1;
    }
    
    /**
     *  \brief   McASP callback function called up on the data transfer completion
     *
     *  \param  arg   [IN]  - Application specific callback argument
     *  \param  ioBuf [IN]  - McASP IO buffer
     *
     *  \return    None
     */
    void mcaspAppCallback(void *arg, MCASP_Packet *ioBuf)
    {
    	/* Callback is triggered by Rx completion */
    	if(ioBuf->cmd == MCASP_READ)
    	{
    		rxFlag++;
    
    		if(rxFrameIndex == 0)
    		{
    			rxFrameIndex = 1;
    		}
    		else
    		{
    			rxFrameIndex = 0;
    		}
    
    		/* Post semaphore */
    		Semaphore_post(semR);
    	}
    
    	/* Callback is triggered by Tx completion */
    	if(ioBuf->cmd == MCASP_WRITE)
    	{
    		if(txFrameIndex == 0)
    		{
    			txFrameIndex = 1;
    		}
    		else
    		{
    			txFrameIndex = 0;
    		}
    
    		txFlag++;
    
    		/* Post semaphore */
    		Semaphore_post(semT);
    	}
    }
    
    /**
     *  \brief   Initializes McASP data buffers and submits to McASP driver
     *
     *  \return    Aud_EOK on Success or error code
     */
    Aud_STATUS initBuffers(void)
    {
    	Error_Block  eb;
        uint32_t     count = 0;
        IHeap_Handle iheap;
        Int          status;
    
        iheap = HeapMem_Handle_to_xdc_runtime_IHeap(heapHandle);
        Error_init(&eb);
    
        /* Allocate buffers for the McASP data exchanges */
        for(count = 0; count < NUM_BUFS; count++)
        {
            rxBuf[count] = Memory_calloc(iheap, (BUFSIZE * RX_NUM_SERIALIZER),
            						     BUFALIGN, &eb);
            if(NULL == rxBuf[count])
            {
                IFPRINT(aud_write("\r\nMEM_calloc failed for Rx\n"));
            }
        }
    
        /* Allocate buffers for the McASP data exchanges */
        for(count = 0; count < NUM_BUFS; count++)
        {
            txBuf[count] = Memory_calloc(iheap, (BUFSIZE * TX_NUM_SERIALIZER),
            							 BUFALIGN, &eb);
            if(NULL == txBuf[count])
            {
                IFPRINT(aud_write("\r\nMEM_calloc failed for Tx\n"));
            }
        }
    
        for(count = 0; count < NUM_BUFS; count++)
        {
            /* Issue the first & second empty buffers to the input stream */
        	memset((uint8_t *)rxBuf[count], 0xFF, (BUFSIZE * RX_NUM_SERIALIZER));
    
    		/* RX frame processing */
    		rxFrame[count].cmd    = MCASP_READ;
    		rxFrame[count].addr   = (void*)(getGlobalAddr(rxBuf[count]));
    		rxFrame[count].size   = BUFSIZE;
    		rxFrame[count].arg    = (uint32_t) mcaspRxChanArg;
    		rxFrame[count].status = 0;
    		rxFrame[count].misc   = 1;   /* reserved - used in callback to indicate asynch packet */
    
    		/* Submit McASP packet for Rx */
    		status = mcaspSubmitChan(hMcaspRxChan, &rxFrame[count]);
    		if((status != MCASP_COMPLETED) && (status != MCASP_PENDING))
    		{
    			IFPRINT(aud_write("mcaspSubmitChan for Rx Failed\n"));
    			return (Aud_EFAIL);
    		}
        }
    
        for(count = 0; count < NUM_BUFS; count++)
        {
        	memset((uint8_t *)txBuf[count], 0xCC, (BUFSIZE * TX_NUM_SERIALIZER));
    
    		/* TX frame processing */
    		txFrame[count].cmd    = MCASP_WRITE;
    		txFrame[count].addr   = (void*)(getGlobalAddr(txBuf[count]));
    		txFrame[count].size   = BUFSIZE;
    		txFrame[count].arg    = (uint32_t) mcaspTxChanArg;
    		txFrame[count].status = 0;
    		txFrame[count].misc   = 1;   /* reserved - used in callback to indicate asynch packet */
    
    		/* Submit McASP packet for Tx */
    		status = mcaspSubmitChan(hMcaspTxChan, &txFrame[count]);
    		if((status != MCASP_COMPLETED) && (status != MCASP_PENDING))
    		{
    			IFPRINT(aud_write("mcaspSubmitChan for Tx Failed\n"));
    			return (Aud_EFAIL);
    		}
        }
    
        return (Aud_EOK);
    }
    
    /**
     *  \brief   Configures McASP module and creates the channel
     *           for audio Tx and Rx
     *
     *  \return    Aud_EOK on Success or error code
     */
    Aud_STATUS mcaspAudioConfig(void)
    {
    	Int status;
    
    	hMcaspDevTx  = NULL;
    	hMcaspDevRx  = NULL;
    	hMcaspTxChan = NULL;
    	hMcaspRxChan = NULL;
    
    	/* Initialize McASP Tx and Rx parameters */
    	mcaspTxParams = Mcasp_PARAMS;
    	mcaspRxParams = Mcasp_PARAMS;
    
    	mcaspTxParams.mcaspHwSetup.tx.clk.clkSetupClk = 0x63;
    	mcaspTxParams.mcaspHwSetup.rx.clk.clkSetupClk = 0x23;
    	mcaspRxParams.mcaspHwSetup.rx.clk.clkSetupClk = 0x23;
    	mcaspRxParams.mcaspHwSetup.tx.clk.clkSetupClk = 0x63;
    
    	mcaspTxParams.mcaspHwSetup.glb.pdir |= 0x2000000; //Set Amute pin as output for Tx channel
    
    	/* Initialize eDMA handle */
    	mcaspRxChanParam.edmaHandle  = hEdma1;
    	mcaspTx0ChanParam.edmaHandle = hEdma0;
    	mcaspTx1ChanParam.edmaHandle = hEdma0;
    
    	/* Bind McASP0 for Tx */
    	status = mcaspBindDev(&hMcaspDevTx, CSL_MCASP_0, &mcaspTxParams);
    	if((status != MCASP_COMPLETED) || (hMcaspDevTx == NULL))
    	{
    		IFPRINT(aud_write("mcaspBindDev for Tx Failed\n"));
    		return (Aud_EFAIL);
    	}
    
    	/* Bind McASP1 for Rx */
    	status = mcaspBindDev(&hMcaspDevRx, CSL_MCASP_1, &mcaspRxParams);
    	if((status != MCASP_COMPLETED) || (hMcaspDevRx == NULL))
    	{
    		IFPRINT(aud_write("mcaspBindDev for Rx Failed\n"));
    		return (Aud_EFAIL);
    	}
    
    #ifdef AUDIO_DAC0_TEST
    	/* Create McASP channel for Tx */
    	status = mcaspCreateChan(&hMcaspTxChan, hMcaspDevTx,
    	                         MCASP_OUTPUT,
    	                         &mcaspTx0ChanParam,
    	                         mcaspAppCallback, &txChanMode);
    	if((status != MCASP_COMPLETED) || (hMcaspTxChan == NULL))
    	{
    		IFPRINT(aud_write("mcaspCreateChan for Tx Failed\n"));
    		return (Aud_EFAIL);
    	}
    #else
    	/* Create McASP channel for Tx */
    	status = mcaspCreateChan(&hMcaspTxChan, hMcaspDevTx,
    	                         MCASP_OUTPUT,
    	                         &mcaspTx1ChanParam,
    	                         mcaspAppCallback, &txChanMode);
    	if((status != MCASP_COMPLETED) || (hMcaspTxChan == NULL))
    	{
    		IFPRINT(aud_write("mcaspCreateChan for Tx Failed\n"));
    		return (Aud_EFAIL);
    	}
    #endif
    
    	configAudioDAC();
    
    	/* Create McASP channel for Rx */
    	status = mcaspCreateChan(&hMcaspRxChan, hMcaspDevRx,
    	                         MCASP_INPUT,
    	                         &mcaspRxChanParam,
    	                         mcaspAppCallback, &rxChanMode);
    	if((status != MCASP_COMPLETED) || (hMcaspRxChan == NULL))
    	{
    		IFPRINT(aud_write("mcaspCreateChan for Rx Failed\n"));
    		return (Aud_EFAIL);
    	}
    
    	/* Initialize the buffers and submit for McASP Tx/Rx */
    	if(initBuffers() != Aud_EOK)
    	{
    		IFPRINT(aud_write("McASP Buffer Initialization Failed\n"));
    		return (Aud_EFAIL);
    	}
    
    	return (Aud_EOK);
    }
    
    /**
     *  \brief   Function to exit the test
     *
     *  \return    None
     */
    void testRet(uint32_t status)
    {
    	aud_write("\n\nAudio DC Analog Interface Test Completed!\n");
    
    	testExit(status);
    }
    
    int total_audio_frame_num = 0;
    /**
     *  \brief   Task to echo the input data to output
     *
     *  Waits for the McASP data transfer completion and copies the
     *  Rx data to Tx buffers
     *
     *  \return    Aud_EOK on Success or error code
     */
    Void Audio_echo_Task(void)
    {
        int32_t count;
    
        Semaphore_Params_init(&params);
    
    	/* Create semaphores to wait for buffer reclaiming */
        semR = Semaphore_create(0, &params, &eb);
        semT = Semaphore_create(0, &params, &eb);
    
        /* Forever loop to continuously receive and transmit audio data */
        while (1)
        {
        	if(gblErrFlag)
        	{
        		break;
    		}
    
        	/* Reclaim full buffer from the input stream */
        	Semaphore_pend(semR, BIOS_WAIT_FOREVER);
        	Semaphore_pend(semT, BIOS_WAIT_FOREVER);
    
            /* Reclaim full buffer from the input stream */
        	gtxFrameIndexCount = txFrameIndex;
        	grxFrameIndexCount = rxFrameIndex;
    
    		for(count = 0; count < 0; count++)
    		{
    			asm("* Comment to maintain loops through compiler optimization");
    		}
    
            /* Reclaim empty buffer from the output stream to be reused           */
    
            /* Copy the receive information to the transmit buffer */
            memcpy(txBuf[gtxFrameIndexCount], rxBuf[grxFrameIndexCount], (BUFSIZE * RX_NUM_SERIALIZER));
    		//memcpy(txBuf[gtxFrameIndexCount], (const void *)sineData, (BUFSIZE * RX_NUM_SERIALIZER));
    		//memcpy(txBuf[gtxFrameIndexCount], (const void *)sineData_4ch, (BUFSIZE * RX_NUM_SERIALIZER));
    
            /* Issue full buffer to the output stream                             */
            /* TX frame processing */
    		txFrame[gtxFrameIndexCount].cmd    = MCASP_READ;
    		txFrame[gtxFrameIndexCount].addr   = (void*)(getGlobalAddr(txBuf[gtxFrameIndexCount]));
    		txFrame[gtxFrameIndexCount].size   = (BUFSIZE);
    		txFrame[gtxFrameIndexCount].arg    = (uint32_t) mcaspTxChanArg;
    		txFrame[gtxFrameIndexCount].status = 0;
    		txFrame[gtxFrameIndexCount].misc   = 1;   /* reserved - used in callback to indicate asynch packet */
    
    		mcaspSubmitChan(hMcaspTxChan, &txFrame[gtxFrameIndexCount]);
    
            /* Issue an empty buffer to the input stream                          */
    		rxFrame[grxFrameIndexCount].cmd    = MCASP_WRITE;
    		rxFrame[grxFrameIndexCount].addr   = (void*)(getGlobalAddr(rxBuf[grxFrameIndexCount]));
    		rxFrame[grxFrameIndexCount].size   = (BUFSIZE);
    		rxFrame[grxFrameIndexCount].arg    = (uint32_t) mcaspRxChanArg;
    		rxFrame[grxFrameIndexCount].status = 0;
    		rxFrame[grxFrameIndexCount].misc   = 1;   /* reserved - used in callback to indicate asynch packet */
    
            mcaspSubmitChan(hMcaspRxChan, &rxFrame[grxFrameIndexCount]);
    		
    		total_audio_frame_num++;
    		if (total_audio_frame_num==500)
    		{
    			aud_write("\nTest Passed\n");
    			UART_printf("\nTest Passed\n");
    		}
    	}
    
        testRet(0);
    }
    
    /* Nothing past this point */
    

    We currently don`t support optical audio input, loopback. The interface is only meant for our performance/home audio application developers using the demo provided here:

    http://software-dl.ti.com/processor-sdk-rtos/esd/docs/latest/rtos/index_examples_demos.html#performance-audio-demo

    Regards,

    Rahul