/*
 * mcbspMasterDigLpbk.c
 *
 * This file contains the test / demo code to demonstrate the McBSP driver
 * master functionality using Digital Loopback setup. The file configures 
 * the EVM in master mode.
 *
 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
 *
 *
 *  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.
 *
*/

/* ========================================================================== */
/*                            INCLUDE FILES                                   */
/* ========================================================================== */
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Log.h>
#include <xdc/cfg/global.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Swi.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/task.h>
#include <string.h>
#include <ti/sysbios/knl/Queue.h>

#include <xdc/cfg/global.h>

/* Include EDMA3 Driver */
#include <ti/sdo/edma3/drv/edma3_drv.h>

/* CSL Chip Functional Layer */
#include <ti/csl/csl_chip.h>

/* CSL Cache Functional Layer */
#include <ti/csl/csl_cacheAux.h>

/* CSL CPINTC Include Files. */
#include<ti/csl/csl_cpIntc.h>

/* MCBSP Driver Include File. */
#include <ti/drv/mcbsp/mcbsp_drv.h>
#include <ti/drv/mcbsp/mcbsp_osal.h>

/* PlatformLib Include File */
#include <ti/platform/platform.h>
#include "platform_internal.h"


/* ========================================================================== */
/*                        EXTERNAL FUNCTIONS                                  */
/* ========================================================================== */

extern EDMA3_DRV_Handle edma3init(unsigned int edma3Id, EDMA3_DRV_Result *);

extern void McbspDevice_init(void);

extern int32_t Osal_dataBufferInitMemory(uint32_t dataBufferSize);

/* FPGA Configuration Misc-1 Register offset */
#define MCBSP_FPGA_MISC_REG_OFFSET (0x0C)

/* ========================================================================== */
/*                           MACRO DEFINTIONS                                 */
/* ========================================================================== */
#include "baker_mcbsp.h"
#if 0
#define NUM_BUFS              2             /* Max of 2 outstanding requests  */
#define NUM_OF_CHANNELS       2             /* Number of slots to be used     */
#define BUFSIZE               (80*NUM_OF_CHANNELS)          /* 1K of data transceive          */
#define NUM_OF_CHANNELS_IN_FRAME       16             /* Number of slots to be used     */
#endif
/* Defines the core number responsible for system initialization. */
#define CORE_SYS_INIT         0

/*============================================================================*/
/*                            GLOBAL VARIABLES                                */
/*============================================================================*/

/* Shared Memory Variable to ensure synchronizing MCBSP initialization
 * with all the other cores. */
/* Created an array to pad the cache line with MCBSP_CACHE_LENGTH size */
#pragma DATA_ALIGN   (isMCBSPInitialized, MCBSP_MAX_CACHE_ALIGN)
#pragma DATA_SECTION (isMCBSPInitialized, ".mcbspSharedMem");
volatile Uint32 isMCBSPInitialized[(MCBSP_CACHE_LENGTH / sizeof(Uint32))] = { 0 };

/* Handle to the EDMA driver instance */
#pragma DATA_ALIGN   (hEdma, MCBSP_MAX_CACHE_ALIGN)
EDMA3_DRV_Handle hEdma[(MCBSP_CACHE_LENGTH / sizeof(EDMA3_DRV_Handle))] = { NULL };

/* Handle to MCBSP driver instance */
typedef void* Mcbsp_DevHandle;
Mcbsp_DevHandle  hMcbspDev;

/* Handle to MCBSP driver channel instance */
typedef void* Mcbsp_ChanHandle;
Mcbsp_ChanHandle  hMcbspTxChan;
Mcbsp_ChanHandle  hMcbspRxChan;

/* Core Number Identifier */
UInt32 coreNum = 0xFFFF;

/* Array to hold the pointer to the allocated buffers     */
void* bufRx[NUM_BUFS];
void* bufTx[NUM_BUFS];
#pragma DATA_ALIGN   (mcbspBufRx0, MCBSP_MAX_CACHE_ALIGN)
uint8_t mcbspBufRx0[2*BUFSIZE]={0};
#pragma DATA_ALIGN   (mcbspBufTx0, MCBSP_MAX_CACHE_ALIGN)
uint8_t mcbspBufTx0[2*BUFSIZE]={0};
#pragma DATA_ALIGN   (mcbspBufRx1, MCBSP_MAX_CACHE_ALIGN)
uint8_t mcbspBufRx1[2*BUFSIZE]={0};
#pragma DATA_ALIGN   (mcbspBufTx1, MCBSP_MAX_CACHE_ALIGN)
uint8_t mcbspBufTx1[2*BUFSIZE]={0};
Mcbsp_IOBuf txFrame[NUM_BUFS], rxFrame[NUM_BUFS];


/* Variables to indicate status of EDMA TX and RX requests */
volatile uint32_t edmaTxDone = 0;
volatile uint32_t edmaRxDone = 0;
volatile uint32_t edmaTxCountDone=0;
volatile uint32_t edmaRxCountDone=0;
/**
 * \brief    Mcbsp Sample rate generator default parameters.
 *
 */
Mcbsp_srgConfig mcbspSrgCfg =
{
    FALSE,  // FALSE,                   /* No gsync to be used as input is not CLKS    */
    Mcbsp_ClkSPol_RISING_EDGE, /* Dont care as input clock is not clks        */
    Mcbsp_SrgClk_CLKCPU, //Mcbsp_SrgClk_CLKS, //Mcbsp_SrgClk_CLKCPU,       /* McBSP internal clock to be used             */
    166666667,                 /* Mcbsp internal clock frequency(PLL-SYSCLK6) */
    0                          /* frame sync pulse width (val+1) is used      */
};

/**
 * \brief    Mcbsp device creation default parameters.
 *
 */
const Mcbsp_Params Mcbsp_PARAMS =
{
    Mcbsp_DevMode_McBSP,       /* Use the device as MCBSP                     */
    Mcbsp_OpMode_DMAINTERRUPT, /* Use DMA mode of operation                   */
    TRUE,                      /* cache coherency taken care of by driver     */
    Mcbsp_EmuMode_FREE, //Mcbsp_EmuMode_SOFT_STOP,   /* Soft mode is to be enabled                  */
    Mcbsp_Loopback_DISABLE,    /* Loop back mode disabled                     */
    &mcbspSrgCfg,              /* sample rate generator configuration         */
    NULL,                      /* TX pending buffer queue from application    */
    NULL,                      /* TX floating buffer queue in DMA             */
    NULL,                      /* RX pending buffer queue from application    */
    NULL                       /* RX floating buffer queue in DMA             */
};

#pragma DATA_ALIGN(loopJob, MCBSP_MAX_CACHE_ALIGN)
static Int32 loopJob[16] = {
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0
};

/**< settings to configure the TX or RX hardware sections                 */
Mcbsp_DataConfig mcbspChanConfig =
{
    Mcbsp_Phase_SINGLE,
    Mcbsp_WordLength_32,
    Mcbsp_WordLength_32,    /* Dont care for single phase*/
    NUM_OF_CHANNELS_IN_FRAME,
    0,      // Only using single phase, hence num channels is 0
    Mcbsp_FrmSync_DETECT,
    Mcbsp_DataDelay_0_BIT, //Mcbsp_DataDelay_1_BIT,
    Mcbsp_Compand_OFF_MSB_FIRST,
    Mcbsp_BitReversal_DISABLE,
    Mcbsp_IntMode_ON_SYNCERR,
    Mcbsp_RxJust_RZF, //Mcbsp_RxJust_RSE, //Mcbsp_RxJust_RZF,  /* Dont care for TX         */
    Mcbsp_DxEna_ON, //Mcbsp_DxEna_ON
};

/**< clock setup for the TX section                     */
Mcbsp_ClkSetup mcbspClkConfigTx =
{
		Mcbsp_FsClkMode_EXTERNAL, //Mcbsp_FsClkMode_INTERNAL,//Mcbsp_FsClkMode_EXTERNAL,
    8000,                   /* 96KHz                   */
    Mcbsp_TxRxClkMode_EXTERNAL, //Mcbsp_TxRxClkMode_INTERNAL,//Mcbsp_TxRxClkMode_EXTERNAL,
    Mcbsp_FsPol_ACTIVE_HIGH,
    Mcbsp_ClkPol_RISING_EDGE
};

/**< clock setup for the RX section                     */
Mcbsp_ClkSetup mcbspClkConfigRx =
{
		Mcbsp_FsClkMode_EXTERNAL, //Mcbsp_FsClkMode_INTERNAL, //Mcbsp_FsClkMode_EXTERNAL,
    8000,                   /* 96KHz                   */
    Mcbsp_TxRxClkMode_EXTERNAL, //Mcbsp_TxRxClkMode_INTERNAL, //Mcbsp_TxRxClkMode_EXTERNAL, //Mcbsp_TxRxClkMode_EXTERNAL,
    Mcbsp_FsPol_ACTIVE_HIGH,
    Mcbsp_ClkPol_FALLING_EDGE
};

/**< Multi channel setup                                                      */
Mcbsp_McrSetup mcbspMultiChanCtrl =
{
	Mcbsp_McmMode_ALL_CHAN_ENABLED_UNMASKED, //Mcbsp_McmMode_ALL_CHAN_DISABLED_UNMASKED, //Mcbsp_McmMode_ALL_CHAN_ENABLED_UNMASKED,
    Mcbsp_PartitionMode_CHAN_0_15,
    Mcbsp_PartitionMode_CHAN_16_31,
    Mcbsp_PartitionMode_2
};

Mcbsp_ChanParams mcbspChanparamTx =
{
    Mcbsp_WordLength_32,  /* wordlength configured    */
    &loopJob[0],          /* loop job buffer internal */
    8,                    /* user loopjob length      */
    NULL,                 /* global error callback    */
    NULL,                 /* edma Handle              */
    1,                    /* EDMA event queue         */
    8,                    /* hwi number               */
    Mcbsp_BufferFormat_MULTISLOT_NON_INTERLEAVED,
    TRUE,                 /* FIFO mode enabled        */
    &mcbspChanConfig,     /* channel configuration    */
    &mcbspClkConfigTx,    /* clock configuration      */
    &mcbspMultiChanCtrl,  /* multi channel control    */
    0x0000000a,
    0x00,
    0x00,
    0x00
};

Mcbsp_ChanParams mcbspChanparamRx =
{
    Mcbsp_WordLength_32,  /* wordlength configured    */
    &loopJob[0],          /* loop job buffer internal */
    8,                    /* user loopjob length      */
    NULL,                 /* global error callback    */
    NULL,                 /* edma Handle              */
    2,                    /* EDMA event queue         */
    8,                    /* hwi number               */
    Mcbsp_BufferFormat_MULTISLOT_NON_INTERLEAVED,
    TRUE,                 /* FIFO mode enabled        */
    &mcbspChanConfig,     /* channel configuration    */
    &mcbspClkConfigRx,    /* clock configuration      */
    &mcbspMultiChanCtrl,  /* multi channel control    */
    0x0000000a,
    0x00,
    0x00,
    0x00
};


/* ========================================================================== */
/*                           FUNCTION DEFINITIONS                             */
/* ========================================================================== */

/*
 *   This is the application's callback function. The driver will
 *   call this function whenever an EDMA I/O operation is over.
 *
 */

/* Variables to indicate status of EDMA TX and RX requests */
unsigned char toggleledvaluegpio14, toggleledvaluegpio15;
int mcbspAppCallbackCnt = 0;
volatile uint32_t edmaMcbspTxCount=0;
volatile uint32_t edmaMcbspRxCount=0;
volatile uint32_t edmaMcbspTxRxCnt=0;
volatile uint32_t edmaMcbspTxRxPeriod=0, edmaMcbspErrCount= 0, edmaMcbspTxCountfree=0, edmaMcbspRxCountfree=0;
int32_t mcbspmoderecived = 0;
void mcbspAppCallbackTx(void* arg, Mcbsp_IOBuf *ioBuf)
{
	  int32_t mode;
    int32_t *pmode = (int32_t *)arg;

    mcbspAppCallbackCnt++;
    mode = *pmode;
    if (mode == MCBSP_MODE_OUTPUT)
    {
        edmaMcbspTxCount++;
        Semaphore_post(semMcbspTx);
        edmaMcbspTxCountfree++;
    }
    else
    {
    	edmaMcbspErrCount++;
    	mcbspmoderecived= mode;
    }
    return;
}
void mcbspAppCallbackRx(void* arg, Mcbsp_IOBuf *ioBuf)
{
	int32_t mode;
    int32_t *pmode = (int32_t *)arg;

    mcbspAppCallbackCnt++;
    mode = *pmode;
    if (mode == MCBSP_MODE_INPUT)
   	{
        edmaMcbspRxCount++;
        Semaphore_post(semMcbspRx);
        edmaMcbspRxCountfree++;
#if 0
        edmaMcbspTxRxPeriod++;
    	clk5msfun_swipost040();
    	swipost040();
#if 1

    	if ((edmaMcbspTxRxPeriod & 0x1) == 0)
    	{
    		swipost080();
    	}
    	if ((edmaMcbspTxRxPeriod & 0x3) == 0)
    	{
    		swipost160();
    	}
    	if ((edmaMcbspTxRxPeriod == 6) || (edmaMcbspTxRxPeriod == 12))
    	{
    		swipost240();
    	}
#endif
    	if (edmaMcbspTxRxPeriod == 12)
    		edmaMcbspTxRxPeriod=0;
#endif

    }
    else
    {
    	edmaMcbspErrCount++;
    	mcbspmoderecived= mode;
    }
    return;
}



void testMcBSPLoop(void);

/*
 * \brief   This function demostrates the use of Mcbsp using digital loopback
 *          communication setup.
 *
 * \param   None
 *
 * \return  None
 */

int mcbspInitDone = 0;
int rxStartCnt = 0;
int txStartCnt = 0;
//void mcbspTxLoop(UArg arg0, UArg arg1);
//void mcbspRxLoop(UArg arg0, UArg arg1);

uint32_t mcbspTxDone = 0, mcbspRxDone = 0;
int edmaSuccessCnt=0, edmaErrorCnt=0;
int edmaDebug=0;
int mcbspRxBufEdmaIndex = 1;
int mcbspTxBufEdmaIndex = 0;
int maxSubmitcnt = 2;
int sendMcbspRxTxCnt = 0;
#pragma DATA_ALIGN   (loopbuf, MCBSP_MAX_CACHE_ALIGN)
uint8_t loopbuf[NUM_OF_CHANNELS] [CHAN_BUFSIZE]= {0};
int debugMcbspIssue = 0;

#pragma DATA_ALIGN   (loopbuf_rx, MCBSP_MAX_CACHE_ALIGN)
int16_t loopbuf_rx[NUM_OF_CHANNELS] [NUM_OF_FRAMES]= {0};
#pragma DATA_ALIGN   (loopbuf_tx, MCBSP_MAX_CACHE_ALIGN)
int16_t loopbuf_tx[NUM_OF_CHANNELS] [NUM_OF_FRAMES]= {0};


void mcbspChanBuf(int bufchan, int edmachan, int Index, int chansizeinbytes, int writesel)
{

	int32_t *ptr_32;
	int16_t *ptr_16;
	int len, i;
	int temp = (int) SLOT_WORD_WIDTH_IN_BYTES;
	len = chansizeinbytes >> 2;

	if (writesel)
	{
		ptr_16 = (int16_t *) &loopbuf_rx[bufchan][0];  // loopbuf_tx
		ptr_32 = (int32_t *)(((uint8_t *)bufTx[Index])+ (edmachan*chansizeinbytes));
		for (i = 0; i < len; i++)
		{
			*ptr_32++ = (int32_t) *ptr_16++;
		}
	}
	else
	{
		ptr_16 = (int16_t *) &loopbuf_rx[bufchan][0];
		ptr_32 = (int32_t *)(((uint8_t *)bufRx[Index])+ (edmachan*chansizeinbytes));
		for (i = 0; i < len; i++)
		{
			*ptr_16++ = (int16_t) *ptr_32++;
		}
	}

}

 void bakerMcbspTask(UArg arg0, UArg arg1)
{
    /**< Mcbsp device params                                                  */
    Mcbsp_Params  mcbspParams;
    /**< Mcbsp sample rate configuration parameters                           */
    Mcbsp_srgConfig  mcbspSrgParams;

    /**< Queue to hold the pending packets received from the application      */
    Queue_Struct  txQueuePendingList, rxQueuePendingList;
    /**< Queue to manage floating packets in DMA                              */
    Queue_Struct  txQueueFloatingList, rxQueueFloatingList;

    uint32_t count   = 0, tempCount = 0;
    int32_t  status  = 0, retval = 0, i;
    int32_t  txChanMode = MCBSP_MODE_OUTPUT;
    int32_t  rxChanMode = MCBSP_MODE_INPUT;
    uint32_t mcbspTxDone = 0, mcbspRxDone = 0;
	uint8_t *ptr;
	int  result=FALSE;

    while(mcbspInitDone == 0)
    {
    	Task_sleep(1);
    }
    mcbspInitDone++;
    /* Initialize the OSAL */
    if (Osal_dataBufferInitMemory(BUFSIZE) < 0)
    {
	    Log_info1 ("Debug(Core %d): Error: Unable to initialize the OSAL. \n", coreNum);
	    return;
    }

    /* update EDMA3 handle to channel parameters */
    mcbspChanparamTx.edmaHandle = hEdma[0];
    mcbspChanparamRx.edmaHandle = hEdma[0];

    /* create the pending and floating queue for the TX channel           */
    Queue_construct(&txQueuePendingList, NULL);
    Queue_construct(&txQueueFloatingList, NULL);

    /* create the pending and floating queue for the RX channel           */
    Queue_construct(&rxQueuePendingList, NULL);
    Queue_construct(&rxQueueFloatingList, NULL);

    /* configure the SRG properties                                           */
    /* use Mcbsp intenal clock      */
    //mcbspSrgParams.srgInputClkMode = Mcbsp_SrgClk_CLKCPU;
    /* 1 bit width framesync        */
    //mcbspSrgParams.srgFrmPulseWidth = 0;
    /* internal clock frequncy      */
    //mcbspSrgParams.srgrInputFreq = 166666667; /* 166.67 MHz - SYSCLK6 */

    mcbspParams                 = Mcbsp_PARAMS;
    //mcbspParams.mode            = Mcbsp_DevMode_McBSP;
    //mcbspParams.opMode          = Mcbsp_OpMode_DMAINTERRUPT;
    //mcbspParams.enablecache     = TRUE;
    //mcbspParams.emulationMode   = Mcbsp_EmuMode_FREE;
    //mcbspParams.dlbMode         = Mcbsp_Loopback_ENABLE;//Mcbsp_Loopback_DISABLE;
    mcbspParams.srgSetup        = &mcbspSrgParams;
    mcbspParams.txQPendingList  = &txQueuePendingList;
    mcbspParams.txQFloatingList = &txQueueFloatingList;
    mcbspParams.rxQPendingList  = &rxQueuePendingList;
    mcbspParams.rxQFloatingList = &rxQueueFloatingList;

    /* Bind the driver instance with device instance */
    status = mcbspBindDev(&hMcbspDev, coreNum, &mcbspParams);

    if (status != MCBSP_STATUS_COMPLETED)
    {
        Log_info1 ("Debug(Core %d): MCBSP LLD Bind Device Failed\n", coreNum);
        return;
    }

    /* Create a RX channel for receiving */
    status = mcbspCreateChan(&hMcbspRxChan, hMcbspDev, MCBSP_MODE_INPUT, &mcbspChanparamRx, mcbspAppCallbackRx, &rxChanMode);
    if (MCBSP_STATUS_COMPLETED != status)
    {
        Log_info1 ("Debug(Core %d): Error: Create Channel (RX) failed\n", coreNum);
        return;
    }

    /* Create a TX channel for the transmission */
    status = mcbspCreateChan(&hMcbspTxChan, hMcbspDev, MCBSP_MODE_OUTPUT, &mcbspChanparamTx, mcbspAppCallbackTx, &txChanMode);
    if (MCBSP_STATUS_COMPLETED != status)
    {
        Log_info1 ("Debug(Core %d): Error: Create Channel (TX) failed\n", coreNum);
        return;
    }

    /* create the buffers required for the TX and RX operations */
    for (count = 0; count < (NUM_BUFS); count++)
    {
        bufTx[count] = (uint8_t *)Osal_mcbspDataBufferMalloc(BUFSIZE);
        bufRx[count] = (uint8_t *)Osal_mcbspDataBufferMalloc(BUFSIZE);

        if (bufTx[count] == NULL)
        {
            Log_info2 ("Debug(Core %d): Error: Tx Buffer (%d) Memory Allocation Failed\n", coreNum, count);
            return;
        }
        if (bufRx[count] == NULL)
        {
            Log_info2 ("Debug(Core %d): Error: Rx Buffer (%d) Memory Allocation Failed\n", coreNum, count);
            return;
        }
    }

    /* Fill the buffers with known data and transmit the same and 
       check if the same pattern is received */
    for (count = 0; count < (NUM_BUFS); count++)
    {
        memset((uint8_t *)bufTx[count], 0, BUFSIZE);
}

    for (i=0; i < maxSubmitcnt; i++)
    {
	mcbspRxBufEdmaIndex = (mcbspRxBufEdmaIndex +1)%NUM_BUFS;
    memset((uint8_t *)bufRx[mcbspRxBufEdmaIndex], 0, BUFSIZE);
    	/* RX frame processing */
    	rxFrame[mcbspRxBufEdmaIndex].cmd = Mcbsp_IOBuf_Cmd_READ;
    	rxFrame[mcbspRxBufEdmaIndex].addr = (void*)bufRx[mcbspRxBufEdmaIndex];
    	rxFrame[mcbspRxBufEdmaIndex].size = BUFSIZE;
    	rxFrame[mcbspRxBufEdmaIndex].arg = (uint32_t) hMcbspRxChan;
    	rxFrame[mcbspRxBufEdmaIndex].status = MCBSP_STATUS_COMPLETED;
        rxFrame[mcbspRxBufEdmaIndex].misc = 1;   /* reserved - used in callback to indicate asynch packet */


        status = mcbspSubmitChan(hMcbspRxChan, (void *)&rxFrame[mcbspRxBufEdmaIndex]);
        rxStartCnt++;
        if (status != MCBSP_STATUS_PENDING)
        {
        Log_info2 ("Debug(Core %d): Error: RX buffer submission in iteration-%d FAILED\n", coreNum, i);
            retval = 1;
        }
        else
        {
        //Log_info2 ("Debug(Core %d): RX buffer in iteration-%d is submitted to MCBSP driver\n", coreNum, newcount);
        }

    } // End of simultaenous submits.

    for (i=0; i < maxSubmitcnt; i++)
    {

    	mcbspTxBufEdmaIndex = (mcbspTxBufEdmaIndex +1) % NUM_BUFS;
        /* TX frame processing */
    	txFrame[mcbspTxBufEdmaIndex].cmd = Mcbsp_IOBuf_Cmd_WRITE;
    	txFrame[mcbspTxBufEdmaIndex].addr = (void*)bufTx[mcbspTxBufEdmaIndex];
    	txFrame[mcbspTxBufEdmaIndex].size = BUFSIZE;
    	txFrame[mcbspTxBufEdmaIndex].arg = (uint32_t)hMcbspTxChan;
    	txFrame[mcbspTxBufEdmaIndex].status = MCBSP_STATUS_COMPLETED;
    	txFrame[mcbspTxBufEdmaIndex].misc = 1;   /* reserved - used in callback to indicate asynch packet */

    	status = mcbspSubmitChan(hMcbspTxChan, (void *)&txFrame[mcbspTxBufEdmaIndex]);
    	txStartCnt++;
        if (status != MCBSP_STATUS_PENDING)
        {
    		Log_info2 ("Debug(Core %d): Error: TX frames submission in iteration-%d FAILED\n", coreNum, i);
            retval = 1;
        }
        else
        {
    		//Log_info2 ("Debug(Core %d): TX frames in iteration-%d are submitted to MCBSP driver\n", coreNum, newcount);
    	}
        }

    mcbspInitDone=2;
    //Task_sleep(2);
    while(1)
    {
    	{
        /* Wait for TX and RX processing to complete */
    		result = Semaphore_pend(semMcbspRx, BIOS_WAIT_FOREVER); //5000);
    		if (result == TRUE) //(edmaMcbspRxCount)
        {
    			edmaMcbspRxCount--;
    			mcbspRxBufEdmaIndex = (mcbspRxBufEdmaIndex +1) % NUM_BUFS;

    			/* Invalidate the Cache Contents */
    			Mcbsp_osalBeginMemAccess ((void *)bufRx[mcbspRxBufEdmaIndex], BUFSIZE);
    			mcbspChanBuf(0, 0, mcbspRxBufEdmaIndex, CHAN_BUFSIZE, 0);
    			mcbspChanBuf(1, 1, mcbspRxBufEdmaIndex, CHAN_BUFSIZE, 0);
    			//memset((uint8_t *)bufRx[mcbspRxBufEdmaIndex], 0, BUFSIZE);
    			Mcbsp_osalEndMemAccess ((void *)bufRx[mcbspRxBufEdmaIndex], BUFSIZE);



        /* RX frame processing */
    			rxFrame[mcbspRxBufEdmaIndex].cmd = Mcbsp_IOBuf_Cmd_READ;
    			rxFrame[mcbspRxBufEdmaIndex].addr = (void*)bufRx[mcbspRxBufEdmaIndex];
    			rxFrame[mcbspRxBufEdmaIndex].size = BUFSIZE;
    			rxFrame[mcbspRxBufEdmaIndex].arg = (uint32_t) hMcbspRxChan;
    			rxFrame[mcbspRxBufEdmaIndex].status = MCBSP_STATUS_COMPLETED;
    			rxFrame[mcbspRxBufEdmaIndex].misc = 1;   /* reserved - used in callback to indicate asynch packet */

    			status = mcbspSubmitChan(hMcbspRxChan, (void *)&rxFrame[mcbspRxBufEdmaIndex]);
    			rxStartCnt++;
        if (status != MCBSP_STATUS_PENDING)
        {
    				Log_info2 ("Debug(Core %d): Error: RX buffer submission in iteration-%d FAILED\n", coreNum, rxStartCnt);
            retval = 1;
        }
        else
        {
    				//Log_info2 ("Debug(Core %d): RX buffer in iteration-%d is submitted to MCBSP driver\n", coreNum, newcount);
    			}
#if 1
    			toggleledvaluegpio14 = ~toggleledvaluegpio14;
    			if (toggleledvaluegpio14 & 1)
    			{
    				gpioSetOutput(GPIO_14);
    			}
    			else
    			{
    				gpioClearOutput(GPIO_14);
        }
#endif
    		} // End of if()
    		else
    			while(1);
    	} // End of Rx While
    	{
    		/* Wait for TX and RX processing to complete */
    		result = Semaphore_pend(semMcbspTx,BIOS_WAIT_FOREVER); // 5000);

    		if (/* (edmaMcbspTxCount) && */(result == TRUE))
    		{
    			edmaMcbspTxCount--;
        /* TX frame processing */
    			mcbspTxBufEdmaIndex = (mcbspTxBufEdmaIndex +1)% NUM_BUFS;
    			Mcbsp_osalBeginMemAccess ((void *)bufTx[mcbspTxBufEdmaIndex], BUFSIZE);
    			mcbspChanBuf(1, 0, mcbspTxBufEdmaIndex, CHAN_BUFSIZE, 1);
    			mcbspChanBuf(0, 1, mcbspTxBufEdmaIndex, CHAN_BUFSIZE, 1);
    			if (debugMcbspIssue)
    			{
    				memset((uint8_t *)bufTx[mcbspTxBufEdmaIndex], 0, BUFSIZE);
    			}
    			Mcbsp_osalEndMemAccess ((void *)bufTx[mcbspTxBufEdmaIndex], BUFSIZE);

    			txFrame[mcbspTxBufEdmaIndex].cmd = Mcbsp_IOBuf_Cmd_WRITE;
    			txFrame[mcbspTxBufEdmaIndex].addr = (void*)bufTx[mcbspTxBufEdmaIndex];
    			txFrame[mcbspTxBufEdmaIndex].size = BUFSIZE;
    			txFrame[mcbspTxBufEdmaIndex].arg = (uint32_t)hMcbspTxChan;
    			txFrame[mcbspTxBufEdmaIndex].status = MCBSP_STATUS_COMPLETED;
    			txFrame[mcbspTxBufEdmaIndex].misc = 1;   /* reserved - used in callback to indicate asynch packet */

    			status = mcbspSubmitChan(hMcbspTxChan, (void *)&txFrame[mcbspTxBufEdmaIndex]);
    			txStartCnt++;
        if (status != MCBSP_STATUS_PENDING)
        {
    				Log_info2 ("Debug(Core %d): Error: TX frames submission in iteration-%d FAILED\n", coreNum, txStartCnt);
            retval = 1;
        }
        else
        {
    				//Log_info2 ("Debug(Core %d): TX frames in iteration-%d are submitted to MCBSP driver\n", coreNum, newcount);
        }
#if 1
    			toggleledvaluegpio15 = ~toggleledvaluegpio15;
    			if (toggleledvaluegpio15 & 1)
            {
    				gpioSetOutput(GPIO_15);
        	        }
    			else
        {
    				gpioClearOutput(GPIO_15);
    }
#endif
#if 1
    			edmaMcbspTxRxPeriod++;
    			clk5msfun_swipost040();
    			swipost040();
#if 1

    			if ((edmaMcbspTxRxPeriod & 0x1) == 0)
    {
    				swipost080();
    }
    			if ((edmaMcbspTxRxPeriod & 0x3) == 0)
    {
    				swipost160();
    }
    			if ((edmaMcbspTxRxPeriod == 6) || (edmaMcbspTxRxPeriod == 12))
    			{
    				swipost240();
    }
#endif
    			if (edmaMcbspTxRxPeriod == 12)
    				edmaMcbspTxRxPeriod=0;
#endif
    		} //if (edmaMcbspTxCount)
    		else
    			while(1);
    	}  // End of Tx While

    } // while(1)
} // End of program

/*
 * \brief  Void main(Void)
 *
 *         Main function of the sample application. This function calls the
 *         function to configure the mcbsp instance.
 *
 * \param  None
 *
 * \return None
 */
Void myStartupFxn(Void)
{

	//BIOS_start();
}
Void mcbspmain0(Void);
/*

Void main(void)
{
	mcbspmain0();
}
*/
Void mcbspmain(Void)
{
    Task_Params taskParams;
    EDMA3_DRV_Result edmaResult = 0;
    uint8_t uchValue;

    /* Get the core number. */
    coreNum = CSL_chipReadReg (CSL_CHIP_DNUM);

#ifdef SIMULATOR_SUPPORT
#warn MCBSP Digital Loopback example is not supported on SIMULATOR !!!
    Log_info0 ("MCBSP Digital Loopback example is not supported on SIMULATOR. Exiting!\n");
    return;
#else
    Log_info1 ("Debug(Core %d): Running MCBSP Digital Loopback example on the DEVICE\n", coreNum);
#endif

    /* Initialize the system only if the core was configured to do so. */
    if (coreNum == CORE_SYS_INIT)
    {
        Log_info1 ("Debug(Core %d): System Initialization for MCBSP\n", coreNum);
#if 0
        /* Drive McBSP_AMC_EN# high. Output SLCLKs, TxCLKs, RxCLKs, FSTs, FSRs as Hi-Z. 
         * These clocks and syncs are tri-stated and McBSP is accessed over 80-pin header */
        if (0 != (platform_fpgaWriteConfigReg(MCBSP_FPGA_MISC_REG_OFFSET, 11)))
        {
            Log_info1 ("Debug(Core %d): FPGA McBSP_AMC_EN# register WRITE failed \n", coreNum);
            return;
        }
        /* DEBUG: Verify if FPGA register is configured correctly */
        if (0 != (platform_fpgaReadConfigReg(MCBSP_FPGA_MISC_REG_OFFSET, &uchValue)))
        {
            Log_info1 ("Debug(Core %d): FPGA McBSP_AMC_EN# register READ failed \n", coreNum);
            return;
        }
        if (11 != uchValue)
        {
            Log_info1 ("Debug(Core %d): FPGA McBSP_AMC_EN# register setting failed \n", coreNum);
            return;
        }
        else
        {
            Log_info2 ("Debug(Core %d): FPGA McBSP_AMC_EN# register is set to %d \n", coreNum, uchValue);
        }
#endif
        /* MCBSP Driver Initialization: This should always be called before
         * invoking the MCBSP Driver. */
        mcbspInit();

        /* Device Specific MCBSP Initializations */
        McbspDevice_init();
        
        /* MCBSP Driver is operational at this time. */
        Log_info1 ("Debug(Core %d): MCBSP Driver Initialization Done\n", coreNum);

        /* Write to the SHARED memory location at this point in time. The other cores cannot execute
         * till the MCBSP Driver is up and running. */
        isMCBSPInitialized[0] = 1;

        /* The MCBSP IP block has been initialized. We need to writeback the cache here because it will
         * ensure that the rest of the cores which are waiting for MCBSP to be initialized would now be
         * woken up. */
        CACHE_wbL1d ((void *) &isMCBSPInitialized[0], MCBSP_MAX_CACHE_ALIGN, CACHE_FENCE_WAIT);
    }
    else
    {
        /* All other cores need to wait for the MCBSP to be initialized before they proceed with the test. */ 
        Log_info1 ("Debug(Core %d): Waiting for MCBSP to be initialized.\n", coreNum);

        /* All other cores loop around forever till the MCBSP is up and running. 
         * We need to invalidate the cache so that we always read this from the memory. */
        while (isMCBSPInitialized[0] == 0)
            CACHE_invL1d ((void *) &isMCBSPInitialized[0], MCBSP_MAX_CACHE_ALIGN, CACHE_FENCE_WAIT);

        Log_info1 ("Debug(Core %d): MCBSP can now be used.\n", coreNum);
    }

    /* Initialize EDMA3 library */
    hEdma[0] = edma3init(0, &edmaResult);

    if (edmaResult != EDMA3_DRV_SOK)
    {
      /* Report EDMA Error */
      Log_info1("Debug(Core %d): EDMA Driver Initialization FAILED\n", coreNum);
    }
    else
    {
      Log_info1("Debug(Core %d): EDMA Driver Initialization Done\n", coreNum);
    }
	gpioSetDirection(GPIO_14, GPIO_OUT );
	gpioSetDirection(GPIO_15, GPIO_OUT );
    mcbspInitDone = 1;
#if 0
    /* Create the Digital Loopback Application Task */
    Task_Params_init(&taskParams);
    taskParams.priority = 5;
    Task_create(bakerMcbspInit2, &taskParams, NULL);
#endif

    /* Start BIOS */
    //BIOS_start();

    return;
}

void evbplatformInit(void)
{
    uint8_t uchValue;
    /* Drive McBSP_AMC_EN# high. Output SLCLKs, TxCLKs, RxCLKs, FSTs, FSRs as Hi-Z.
     * These clocks and syncs are tri-stated and McBSP is accessed over 80-pin header */
    if (0 != (platform_fpgaWriteConfigReg(MCBSP_FPGA_MISC_REG_OFFSET, 11)))
    {
        Log_info1 ("Debug(Core %d): FPGA McBSP_AMC_EN# register WRITE failed \n", coreNum);
    return;
}
    /* DEBUG: Verify if FPGA register is configured correctly */
    if (0 != (platform_fpgaReadConfigReg(MCBSP_FPGA_MISC_REG_OFFSET, &uchValue)))
    {
        Log_info1 ("Debug(Core %d): FPGA McBSP_AMC_EN# register READ failed \n", coreNum);
        return;
    }
    if (11 != uchValue)
    {
        Log_info1 ("Debug(Core %d): FPGA McBSP_AMC_EN# register setting failed \n", coreNum);
        return;
    }
    else
    {
        Log_info2 ("Debug(Core %d): FPGA McBSP_AMC_EN# register is set to %d \n", coreNum, uchValue);
    }


}
/* ========================================================================== */
/*                                END OF FILE                                 */
/* ========================================================================== */
