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.

CCS/AWR1642BOOST: integration between CAN drivers and srr_16xx lab

Part Number: AWR1642BOOST
Other Parts Discussed in Thread: SYSBIOS

Tool/software: Code Composer Studio



Hi.

I am currently trying to integrate the CAN driver code into the lab srr_16xx. In order to integrate it I am pasting the code from C:\ti\mmwave_sdk_01_02_00_05\packages\ti\drivers\can\test\common into
the SRR_MSS_initTask function in the mss_main.c file. The modified code is attached.

I managed to make it compile properly but when I try to  debug it i get the following error:

"[Cortex_R4_0] Debug: Launched the Initialization Task
ti.sysbios.family.arm.v7r.vim.Hwi: line 195: E_alreadyDefined: Hwi already defined: intr# 98
xdc.runtime.Main: "src/ti_rtos/HwiP_tirtos.c", line 95: assertion failure
xdc.runtime.Error.raise: terminating execution "

Any clue on how to solve this? My intention is to send the information that is sent through UART also through CAN, but I am not entirely sure how to do so.

Ty
Jaume

/*
 *   @file  mss_main.c
 *
 *   @brief
 *      SRR TI Design  executing on the MSS
 *
 *  \par
 *  NOTE:
 *      (C) Copyright 2018 Texas Instruments, Inc.
 *
 *  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 ********************************
 **************************************************************************/

/* Standard Include Files. */
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <math.h>

/* BIOS/XDC Include Files. */
#include <xdc/std.h>
#include <xdc/cfg/global.h>
#include <xdc/runtime/IHeap.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/Memory.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Event.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/heaps/HeapBuf.h>
#include <ti/sysbios/heaps/HeapMem.h>
#include <ti/sysbios/knl/Event.h>
#include <ti/sysbios/family/arm/v7a/Pmu.h>
#include <ti/sysbios/family/arm/v7r/vim/Hwi.h>

/* mmWave SDK Include Files: */
#include <ti/common/sys_common.h>
#include <ti/drivers/soc/soc.h>
#include <ti/drivers/can/can.h>
#include <ti/drivers/esm/esm.h>
#include <ti/drivers/crc/crc.h>
#include <ti/drivers/uart/UART.h>
#include <ti/drivers/gpio/gpio.h>
#include <ti/drivers/mailbox/mailbox.h>
#include <ti/drivers/pinmux/pinmux.h>
#include <ti/drivers/osal/DebugP.h>
#include <ti/control/mmwavelink/mmwavelink.h>
#include <ti/control/mmwave/mmwave.h>
#include <ti/control/mmwavelink/include/rl_driver.h>
#include <ti/utils/testlogger/logger.h>
#include <ti/drivers/osal/HwiP.h>


/* Application Include Files: */
#include "mss_srr.h"
#include <common/srr_config_consts.h>
#include "common/mmw_messages.h"
#include <ti/utils/cli/cli.h>
#include <ti/drivers/cbuff/cbuff.h>

/**************************************************************************
 *************************** Global Definitions ***************************
 **************************************************************************/

/**
 * @brief
 *  Initialize the MCPI Log Message Buffer
 */
MCPI_LOGBUF_INIT(9216);

/** \brief Number of messages sent */
#define DCAN_APP_TEST_INTERNAL_LOOPBACK 1
#define DCAN_APP_TEST_EXTERNAL_LOOPBACK 2
#define DCAN_APP_TEST_PARITY            3
#define DCAN_APP_TEST_EXTERNAL_DATA     4

/** \brief Number of messages sent */
#define DCAN_APP_TEST_MESSAGE_COUNT     100

/** \brief DCAN input clock - 20MHz */
#define DCAN_APP_INPUT_CLK              (20000000U)
/** \brief DCAN output bit rate - 1MHz */
#define DCAN_APP_BIT_RATE               (1000000U)
/** \brief DCAN Propagation Delay - 700ns */
#define DCAN_APP_PROP_DELAY             (700U)
/** \brief DCAN Sampling Point - 70% */
#define DCAN_APP_SAMP_PT                (70U)

/** \brief DCAN TX message object used */
#define DCAN_TX_MSG_OBJ                 (0x1U)
/** \brief DCAN RX message object used */
#define DCAN_RX_MSG_OBJ                 (0x2U)


/** \brief DCAN Message Object used for PARITY Test */
#define DCAN_NUM_MSG_OBJ                 (0x1)

#define DCAN_MSG_OBJ_1                   (0x4)
#define DCAN_MSG_OBJ_2                   (0x6)

/** \brief Message Object Size*/
#define DCAN_MSG_OBJ_SIZE                (0x20U)

/** \brief DCAN Message Object RAM Address */
#if (defined(SOC_XWR14XX))
#define DCAN_MSG_OBJ_RAM_ADDR_1         ((SOC_XWR14XX_MSS_DCAN_MEM_BASE_ADDRESS) + \
                                         (DCAN_MSG_OBJ_1 * DCAN_MSG_OBJ_SIZE))
#define DCAN_MSG_OBJ_RAM_ADDR_2         ((SOC_XWR14XX_MSS_DCAN_MEM_BASE_ADDRESS) + \
                                         (DCAN_MSG_OBJ_2 * DCAN_MSG_OBJ_SIZE))
#else
#define DCAN_MSG_OBJ_RAM_ADDR_1         ((SOC_XWR16XX_MSS_DCAN_MEM_BASE_ADDRESS) + \
                                         (DCAN_MSG_OBJ_1 * DCAN_MSG_OBJ_SIZE))
#define DCAN_MSG_OBJ_RAM_ADDR_2         ((SOC_XWR16XX_MSS_DCAN_MEM_BASE_ADDRESS) + \
                                         (DCAN_MSG_OBJ_2 * DCAN_MSG_OBJ_SIZE))
#endif

/* Global Variables */
volatile uint32_t       testSelection = 0;
volatile uint32_t       gTxDoneFlag = 0, gRxDoneFlag = 0, gParityErrFlag = 0;
uint32_t                iterationCount = 0U;
volatile uint32_t       gTxPkts = 0, gRxPkts = 0, gErrStatusInt = 0;
CAN_DCANCfgParams       appDcanCfgParams;
CAN_DCANMsgObjCfgParams appDcanTxCfgParams;
CAN_DCANMsgObjCfgParams appDcanRxCfgParams;
CAN_DCANBitTimeParams   appDcanBitTimeParams;
CAN_DCANData            appDcanTxData;
CAN_DCANData            appDcanRxData;
uint32_t                dataLength = 0U;
uint32_t                msgLstErrCnt = 0U;
uint32_t                dataMissMatchErrCnt = 0U;
uint32_t                rxTicks[DCAN_APP_TEST_MESSAGE_COUNT];
uint32_t                txTicks[DCAN_APP_TEST_MESSAGE_COUNT];
uint32_t                minRxTicks;
uint32_t                maxRxTicks;
uint32_t                minTxTicks;
uint32_t                maxTxTicks;
uint32_t                totalTxTicks;
uint32_t                totalRxTicks;
uint32_t                gDisplayStats = 0;

/**
 *  @b Description
 *  @n
 *      This function starts the PMU counter.
 *
 *   @param[in] counter
 *      Counter id used for benchmarking
 *
 *  @retval
 *      Not Applicable.
 */
void Test_benchmarkStart(uint32_t counter)
{
    /* Initialize counter to count cycles */
    Pmu_configureCounter(counter, 0x11, FALSE);

    /* Reset PMU counter */
    Pmu_resetCount(counter);

    /* Start PMU counter */
    Pmu_startCounter(counter);
}

/**
 *  @b Description
 *  @n
 *      This function stops a PMU counter and returns the current
 *      counter value.
 *
 *   @param[in] counter
 *      Counter id used for benchmarking
 *
 *  @retval
 *      Current PMU counter value.
 */
uint32_t Test_benchmarkStop(uint32_t counter)
{
    /* Stop PMU counter */
    Pmu_stopCounter(counter);

    /* Read PMU counter */
    return (Pmu_getCount(counter));
}

/**
 *  @b Description
 *  @n
 *      Application implemented callback function to handle error and status interrupts.
 *
 *   @param[in] handle
 *      Handle to the CAN Driver
 *   @param[in] errStatusResp
 *      Response structure containing the Error and status information
 *
 *  @retval
 *      Not Applicable.
 */
static void DCANAppErrStatusCallback(CAN_Handle handle, CAN_ErrStatusResp* errStatusResp)
{
    gErrStatusInt++;
    if (errStatusResp->parityError == 1)
    {
        gParityErrFlag = 1;
    }
    return;
}

/**
 *  @b Description
 *  @n
 *      Application implemented callback function to handle Tx complete and receive interrupts.
 *
 *   @param[in] handle
 *      Handle to the message object
 *   @param[in] msgObjectNum
 *      Message object number
 *   @param[in] direction
 *      Direction of the object number
 *
 *  @retval
 *      Not Applicable.
 */
static void DCANAppCallback(CAN_MsgObjHandle handle, uint32_t msgObjectNum, CAN_Direction direction)
{
    int32_t     errCode, retVal;

    if (direction == CAN_Direction_TX)
    {
        if (msgObjectNum != DCAN_TX_MSG_OBJ)
        {
            System_printf ("Error: Tx callback received for incorrect Message Object %d\n", msgObjectNum);
            return;
        }
        else
        {
            gTxPkts++;
            gTxDoneFlag = 1;
            return;
        }
    }
    if (direction == CAN_Direction_RX)
    {
        if (msgObjectNum != DCAN_RX_MSG_OBJ)
        {
            System_printf ("Error: Rx callback received for incorrect Message Object %d\n", msgObjectNum);
            return;
        }
        else
        {
            /* Reset the receive buffer */
            memset(&appDcanRxData, 0, sizeof (appDcanRxData));
            dataLength = 0;

            if ((testSelection != DCAN_APP_TEST_EXTERNAL_DATA) && (gRxPkts < DCAN_APP_TEST_MESSAGE_COUNT))
            {
                /* Reset the counter: */
                Test_benchmarkStart(0);
            }
            retVal = CAN_getData (handle, &appDcanRxData, &errCode);
            if (retVal < 0)
            {
                System_printf ("Error: CAN receive data for iteration %d failed [Error code %d]\n", iterationCount, errCode);
                return;
            }

            if ((testSelection != DCAN_APP_TEST_EXTERNAL_DATA) && (gRxPkts < DCAN_APP_TEST_MESSAGE_COUNT))
            {
                /* Stop the counter: */
                rxTicks[gRxPkts] = Test_benchmarkStop(0);

                /* Update the receive statistics: */
                minRxTicks   = (minRxTicks < rxTicks[gRxPkts]) ? minRxTicks : rxTicks[gRxPkts];
                maxRxTicks   = (maxRxTicks > rxTicks[gRxPkts]) ? maxRxTicks : rxTicks[gRxPkts];
                totalRxTicks = totalRxTicks + rxTicks[gRxPkts];
            }

            /* Check if sent data is lost or not */
            if (appDcanRxData.msgLostFlag == 1)
            {
                msgLstErrCnt++;
            }

            /* Validate the data */
            if ((testSelection == DCAN_APP_TEST_INTERNAL_LOOPBACK) || (testSelection == DCAN_APP_TEST_EXTERNAL_LOOPBACK))
            {
                /* Check if sent data has been received */
                if (appDcanRxData.dataLength == appDcanTxData.dataLength)
                {
                    while (dataLength < appDcanRxData.dataLength)
                    {
                        if (appDcanRxData.msgData[dataLength] != appDcanTxData.msgData[dataLength])
                        {
                            dataMissMatchErrCnt++;
                            System_printf ("Error: CAN receive data mismatch for iteration %d at byte %d\n", iterationCount, dataLength);
                        }
                        dataLength++;
                    }
                }
            }
            gRxPkts++;
            gRxDoneFlag = 1;
            return;
        }
    }
}

/**
 * \brief   This function takes I/P Clk frequency, required bit-rate, reference
 *          sampling point, propagation delayon the CAN bus and calculates the
 *          value to be programmed for DCAN BTR register.
 *          This API doesn't do the actual programming. This is
 *          intended to be used as a utility function. And the application
 *          should call the #DCANSetBitTime function to do the actual
 *          programming.
 *
 * \param   clkFreq       I/P clock frequency to DCAN controller in terms of MHz
 * \param   bitRate       Required bit-rate on the CAN bus in KHz
 * \param   refSamplePnt  Reference Sampling point in terms of %
 * \param   propDelay     Required Propagation delay in terms of ns
 * \param   bitTimeParams  Pointer to params where the calculated register
 *                        fields are populated
 *
 * \return  Returns the error status information as STW_SOK for success and
 *          STW_EFAIL when no valid baudrate calculation possible for the
 *          configured baudrate and propagation delay
 */
int32_t DCANAppCalcBitTimeParams(uint32_t               clkFreq,
                                uint32_t                bitRate,
                                uint32_t                refSamplePnt,
                                uint32_t                propDelay,
                                CAN_DCANBitTimeParams*  bitTimeParams)
{
    Double  tBitRef = 1000 * 1000 / bitRate;
    Double  newBaud = 0, newNProp = 0, newNSeg = 0, newSjw = 0, newP = 0;
    Double  nQRef, nProp, fCan, nQ, nSeg, baud, sp, p, newSp = 0;
    float   tQ;

    for (p = 1; p <= 1024; p++)
    {
        tQ    = ((p / clkFreq) * 1000.0);
        nQRef = tBitRef / tQ;

        if ((nQRef >= 8) && (nQRef <= 25))
        {
            nProp = ceil(propDelay / tQ);
            fCan  = clkFreq / p;
            nQ    = fCan / bitRate * 1000;
            nSeg  = ceil((nQ - nProp - 1) / 2);

            if ((nProp <= 8) && (nProp > 0) && (nSeg <= 8) && (nSeg > 0))
            {
                baud = fCan / (1 + nProp + 2 * nSeg) * 1000;

                sp = (1 + nProp + nSeg) / (1 + nProp + nSeg + nSeg) * 100;

                if ((abs(baud - bitRate)) < (abs(newBaud - bitRate)))
                {
                    newBaud  = baud;
                    newNProp = nProp;
                    newNSeg  = nSeg;
                    newSjw   = (nSeg < 4) ? nSeg : 4;
                    newP     = p - 1;
                    newSp    = sp;
                }
                else if ((abs(baud - bitRate)) == (abs(newBaud - bitRate)))
                {
                    if ((abs(sp - refSamplePnt)) < (abs(newSp - refSamplePnt)))
                    {
                        newBaud  = baud;
                        newNProp = nProp;
                        newNSeg  = nSeg;
                        newSjw   = (nSeg < 4) ? nSeg : 4;
                        newP     = p - 1;
                        newSp    = sp;
                    }
                }
            }
        }
    }
    if ((newBaud == 0) || (newBaud > 1000))
    {
        return -1;
    }

    bitTimeParams->baudRatePrescaler    = (((uint32_t) newP) & 0x3F);
    bitTimeParams->baudRatePrescalerExt =
        ((((uint32_t) newP) & 0x3C0) ? (((uint32_t) newP) & 0x3C0) >> 6 : 0);
    bitTimeParams->syncJumpWidth = ((uint32_t) newSjw) - 1;

    /* propSeg = newNProp, phaseSeg = newNSeg, samplePoint = newSp
     * nominalBitTime = (1 + newNProp + 2 * newNSeg), nominalBitRate = newBaud
     * brpFreq  = clkFreq / (brp + 1), brpeFreq = clkFreq / (newP + 1)
     * brp      = bitTimeParams->baudRatePrescaler;
     */

    bitTimeParams->timeSegment1 = newNProp + newNSeg - 1;
    bitTimeParams->timeSegment2 = newNSeg - 1;

    return 0;
}

/**
 *  @b Description
 *  @n
 *      Platform specific intializations.
 *
 *  @retval
 *      Success     - 0
 *  @retval
 *      Error       - <0
 */

static int32_t PlatformInit(void)
{
    int32_t         errCode;
    SOC_Handle      socHandle;
    SOC_Cfg         socCfg;

    /* Initialize the SOC confiugration: */
    memset ((void *)&socCfg, 0, sizeof(SOC_Cfg));

    /* Populate the SOC configuration: */
    socCfg.clockCfg = SOC_SysClock_INIT;

    /* Initialize the SOC Module: This is done as soon as the application is started
     * to ensure that the MPU is correctly configured. */
    socHandle = SOC_init (&socCfg, &errCode);
    if (socHandle == NULL)
    {
        System_printf ("Error: SOC Module Initialization failed [Error code %d]\n", errCode);
        return -1;
    }

#if (defined(SOC_XWR14XX))
    /* Setup the PINMUX to bring out the XWR14xx CAN pins */
    Pinmux_Set_OverrideCtrl(SOC_XWR14XX_PINP5_PADAE, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR14XX_PINP5_PADAE, SOC_XWR14XX_PINP5_PADAE_CAN_TX);
    Pinmux_Set_OverrideCtrl(SOC_XWR14XX_PINR8_PADAD, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR14XX_PINR8_PADAD, SOC_XWR14XX_PINR8_PADAD_CAN_RX);
#else
    /* Setup the PINMUX to bring out the XWR16xx CAN pins */
    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINC13_PADAG, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINC13_PADAG, SOC_XWR16XX_PINC13_PADAG_CAN_TX);

    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINE13_PADAF, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINE13_PADAF, SOC_XWR16XX_PINE13_PADAF_CAN_RX);
#endif

    /* Configure the divide value for DCAN source clock */
    SOC_setPeripheralClock(socHandle, SOC_MODULE_DCAN, SOC_CLKSOURCE_VCLK, 9U, &errCode);

    /* Initialize peripheral memory */
    SOC_initPeripheralRam(socHandle, SOC_MODULE_DCAN, &errCode);

    return 0;
}

static void DCANAppInitParams(CAN_DCANCfgParams*        dcanCfgParams,
                              CAN_DCANMsgObjCfgParams*  dcanTxCfgParams,
                              CAN_DCANMsgObjCfgParams*  dcanRxCfgParams,
                              CAN_DCANData*             dcanTxData)
{
    /*Intialize DCAN Config Params*/

    if (testSelection == DCAN_APP_TEST_PARITY)
    {
        dcanCfgParams->parityEnable         = 1;
        dcanCfgParams->intrLine0Enable      = 1;
        dcanCfgParams->intrLine1Enable      = 0;
        dcanCfgParams->testModeEnable       = 0;
        dcanCfgParams->eccModeEnable        = 1;
        dcanCfgParams->eccDiagModeEnable    = 0;
        dcanCfgParams->sbeEventEnable       = 1;
        dcanCfgParams->stsChangeIntrEnable  = 0;
    }
    else if (testSelection == DCAN_APP_TEST_EXTERNAL_DATA)
    {
        dcanCfgParams->parityEnable         = 0;
        dcanCfgParams->intrLine0Enable      = 1;
        dcanCfgParams->intrLine1Enable      = 1;
        dcanCfgParams->testModeEnable       = 0;
        dcanCfgParams->eccModeEnable        = 0;
        dcanCfgParams->stsChangeIntrEnable  = 0;
    }
    else
    {
        dcanCfgParams->parityEnable         = 0;
        dcanCfgParams->intrLine0Enable      = 1;
        dcanCfgParams->intrLine1Enable      = 1;
        dcanCfgParams->eccModeEnable        = 0;
        dcanCfgParams->testModeEnable       = 1;
        if (testSelection == DCAN_APP_TEST_INTERNAL_LOOPBACK)
        {
            dcanCfgParams->testMode = CAN_DCANTestMode_LPBACK;
            dcanCfgParams->stsChangeIntrEnable  = 0;
        }
        else
        {
            dcanCfgParams->testMode = CAN_DCANTestMode_EXT_LPBACK;
            dcanCfgParams->stsChangeIntrEnable  = 1;
        }
    }

    dcanCfgParams->autoRetransmitDisable = 1;
    dcanCfgParams->autoBusOnEnable       = 0;
    dcanCfgParams->errIntrEnable         = 1;
    dcanCfgParams->autoBusOnTimerVal     = 0;
    dcanCfgParams->if1DmaEnable          = 0;
    dcanCfgParams->if2DmaEnable          = 0;
    dcanCfgParams->if3DmaEnable          = 0;
    dcanCfgParams->ramAccessEnable       = 0;
    dcanCfgParams->appCallBack           = DCANAppErrStatusCallback;

    /*Intialize DCAN tx Config Params*/
    dcanTxCfgParams->xIdFlagMask       = 0x1;
    dcanTxCfgParams->dirMask           = 0x1;
    dcanTxCfgParams->msgIdentifierMask = 0x1FFFFFFF;

    dcanTxCfgParams->msgValid      = 1;
    dcanTxCfgParams->xIdFlag       = CAN_DCANXidType_11_BIT;
    dcanTxCfgParams->direction     = CAN_Direction_TX;
    dcanTxCfgParams->msgIdentifier = 0xC1;

    dcanTxCfgParams->uMaskUsed    = 1;
    if (testSelection == DCAN_APP_TEST_PARITY)
        dcanTxCfgParams->intEnable    = 0;
    else
        dcanTxCfgParams->intEnable    = 1;

    dcanTxCfgParams->remoteEnable = 0;
    dcanTxCfgParams->fifoEOBFlag  = 1;
    dcanTxCfgParams->appCallBack  = DCANAppCallback;

    /*Intialize DCAN Rx Config Params*/
    dcanRxCfgParams->xIdFlagMask       = 0x1;
    dcanRxCfgParams->msgIdentifierMask = 0x1FFFFFFF;
    dcanRxCfgParams->dirMask           = 0x1;

    dcanRxCfgParams->msgValid      = 1;
    dcanRxCfgParams->xIdFlag       = CAN_DCANXidType_11_BIT;
    dcanRxCfgParams->direction     = CAN_Direction_RX;
    dcanRxCfgParams->msgIdentifier = 0xC1;

    dcanRxCfgParams->uMaskUsed    = 1;
    if (testSelection == DCAN_APP_TEST_PARITY)
        dcanRxCfgParams->intEnable    = 0;
    else
        dcanRxCfgParams->intEnable    = 1;

    dcanRxCfgParams->remoteEnable = 0;
    dcanRxCfgParams->fifoEOBFlag  = 1;
    dcanRxCfgParams->appCallBack  = DCANAppCallback;

    /*Intialize DCAN Tx transfer Params*/
    dcanTxData->dataLength = DCAN_MAX_MSG_LENGTH;
    dcanTxData->msgData[0] = 0xA5;
    dcanTxData->msgData[1] = 0x5A;
    dcanTxData->msgData[2] = 0xFF;
    dcanTxData->msgData[3] = 0xFF;
    dcanTxData->msgData[4] = 0xC3;
    dcanTxData->msgData[5] = 0x3C;
    dcanTxData->msgData[6] = 0xB4;
    dcanTxData->msgData[7] = 0x4B;
}

static int32_t dcanParityTest(void)
{
    CAN_Handle              canHandle;
    CAN_MsgObjHandle        txMsgObjHandle;
    CAN_MsgObjHandle        rxMsgObjHandle;
    int32_t                 retVal = 0;
    int32_t                 errCode = 0;
    CAN_OptionTLV           optionTLV;
    uint8_t                 value;
    CAN_DCANEccErrSts       eccErrSts;
    int32_t*                ptrMsgObjMem;

    gTxDoneFlag = 0;

    /* Initialize the DCAN parameters that need to be specified by the application */
    DCANAppInitParams(&appDcanCfgParams,
                      &appDcanTxCfgParams,
                      &appDcanRxCfgParams,
                      &appDcanTxData);

    /* Initialize the CAN driver */
    canHandle = CAN_init(&appDcanCfgParams, &errCode);
    if (canHandle == NULL)
    {
        System_printf ("Error: CAN Module Initialization failed [Error code %d]\n", errCode);
        return -1;
    }

    /* Set the desired bit rate based on input clock */
    retVal = DCANAppCalcBitTimeParams(DCAN_APP_INPUT_CLK / 1000000,
                                            DCAN_APP_BIT_RATE / 1000,
                                            DCAN_APP_SAMP_PT,
                                            DCAN_APP_PROP_DELAY,
                                            &appDcanBitTimeParams);
    if (retVal < 0)
    {
        System_printf ("Error: CAN Module bit time parameters are incorrect \n");
        return -1;
    }

    /* Configure the CAN driver */
    retVal = CAN_configBitTime (canHandle, &appDcanBitTimeParams, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN Module configure bit time failed [Error code %d]\n", errCode);
        return -1;
    }

    /* Setup the transmit message object */
    txMsgObjHandle = CAN_createMsgObject (canHandle, DCAN_MSG_OBJ_1, &appDcanTxCfgParams, &errCode);
    if (txMsgObjHandle == NULL)
    {
        System_printf ("Error: CAN create Tx message object failed [Error code %d]\n", errCode);
        return -1;
    }

    /* Setup the receive message object */
    rxMsgObjHandle = CAN_createMsgObject (canHandle, DCAN_MSG_OBJ_2, &appDcanRxCfgParams, &errCode);
    if (rxMsgObjHandle == NULL)
    {
        System_printf ("Error: CAN create Rx message object failed [Error code %d]\n", errCode);
        return -1;
    }

    /* Send data over Tx message object */
    retVal = CAN_transmitData (txMsgObjHandle, &appDcanTxData, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN transmit data for iteration %d failed [Error code %d]\n", iterationCount, errCode);
        return -1;
    }

    /* Disable parity to corrupt the RAM */
    optionTLV.type = CAN_Option_DCAN_PARITY;
    optionTLV.length = sizeof(uint8_t);
    value = 0;
    optionTLV.value = (void*) &value;

    retVal =  CAN_setOptions(canHandle, &optionTLV, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN set option disable PARITY failed [Error code %d]\n", errCode);
        return -1;
    }

    /* Enable ECC Diagnostics */
    optionTLV.type = CAN_Option_DCAN_ECC_DIAG;
    optionTLV.length = sizeof(uint8_t);
    value = 1;
    optionTLV.value = (void*) &value;

    retVal =  CAN_setOptions(canHandle, &optionTLV, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN set option enable ECC DIAG failed [Error code %d]\n", errCode);
        return -1;
    }

    ptrMsgObjMem = (int32_t *) (DCAN_MSG_OBJ_RAM_ADDR_1);
    /* Corrupting the data in Message RAM in RDA Mode :
     * as 0xC343B44A instead of 0xC343B44B which introduces
     * single bit error for ECC test / Parity Error for Parity test.
     */
    *ptrMsgObjMem = (*ptrMsgObjMem & 0xFFFFFFFE);

    ptrMsgObjMem = (int32_t *) (DCAN_MSG_OBJ_RAM_ADDR_2);

    /* Corrupting the data in Message RAM in RDA Mode :
     * as 0xC343B448 instead of 0xC343B44B which introduces single bit error.
     */
    *ptrMsgObjMem = (*ptrMsgObjMem & 0xFFFFFFFC);

    /* Enable parity to corrupt the RAM */
    optionTLV.type = CAN_Option_DCAN_PARITY;
    optionTLV.length = sizeof(uint8_t);
    value = 1;
    optionTLV.value = (void*) &value;

    retVal =  CAN_setOptions(canHandle, &optionTLV, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN set option enable PARITY failed [Error code %d]\n", errCode);
        return -1;
    }

    /* Reset the receive buffer */
    memset(&appDcanRxData, 0, sizeof (appDcanRxData));
    dataLength = 0;
    retVal = CAN_getData (txMsgObjHandle, &appDcanRxData, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN receive data for iteration %d failed [Error code %d]\n", iterationCount, errCode);
        return -1;
    }

    /* Wait for the parity error interrupt */
    while (gParityErrFlag == 0);

    /* Get the ECC error status */
    optionTLV.type = CAN_Option_DCAN_ECC_ERROR_STATUS;
    optionTLV.length = sizeof(CAN_DCANEccErrSts);
    optionTLV.value = (void*) &eccErrSts;

    retVal =  CAN_getOptions(canHandle, &optionTLV, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN get option ECC status failed [Error code %d]\n", errCode);
        return -1;
    }

    if ((eccErrSts.singleBitErr != 1) || (eccErrSts.doubleBitErr != 1) ||
            (eccErrSts.messageNum != DCAN_MSG_OBJ_1))
    {
        System_printf ("Error: ECC error status check failed. Single bit error %d Double bit error %d Message Number %d\n",
                        eccErrSts.singleBitErr, eccErrSts.doubleBitErr, eccErrSts.messageNum);
        return -1;
    }
    else
    {
        System_printf ("Debug: ECC error status check passed. Single bit error %d Double bit error %d Message Number %d\n",
                        eccErrSts.singleBitErr, eccErrSts.doubleBitErr, eccErrSts.messageNum);
    }

    /* Clear the ECC error status */
    optionTLV.type = CAN_Option_DCAN_CLEAR_ECC_ERROR_STATUS;
    optionTLV.length = sizeof(uint8_t);
    value = 1;
    optionTLV.value = (void*) &value;

    retVal =  CAN_setOptions(canHandle, &optionTLV, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN set option Clear the ECC error status failed [Error code %d]\n", errCode);
        return -1;
    }


    /* Get the ECC Diagnostics error status */
    optionTLV.type = CAN_Option_DCAN_ECC_DIAG_ERROR_STATUS;
    optionTLV.length = sizeof(CAN_DCANEccErrSts);
    optionTLV.value = (void*) &eccErrSts;

    retVal =  CAN_getOptions(canHandle, &optionTLV, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN get option ECC Diagnostics status failed [Error code %d]\n", errCode);
        return -1;
    }

    if ((eccErrSts.singleBitErr != 1) || (eccErrSts.doubleBitErr != 1) ||
            (eccErrSts.messageNum != DCAN_MSG_OBJ_1))
    {
        System_printf ("Error: ECC Diag error status check failed Single bit error %d Double bit error %d\n",
                        eccErrSts.singleBitErr, eccErrSts.doubleBitErr);
        return -1;
    }
    else
    {
        System_printf ("Debug: ECC Diag error status check passed Single bit error %d Double bit error %d\n",
                        eccErrSts.singleBitErr, eccErrSts.doubleBitErr);
    }

    /* Clear the ECC Diagnostics error status */
    optionTLV.type = CAN_Option_DCAN_CLEAR_ECC_DIAG_ERROR_STATUS;
    optionTLV.length = sizeof(uint8_t);
    value = 1;
    optionTLV.value = (void*) &value;

    retVal =  CAN_setOptions(canHandle, &optionTLV, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN set option Clear the ECC Diagnostics error status failed [Error code %d]\n", errCode);
        return -1;
    }

    /* Disable ECC Diagnostics */
    optionTLV.type = CAN_Option_DCAN_ECC_DIAG;
    optionTLV.length = sizeof(uint8_t);
    value = 0;
    optionTLV.value = (void*) &value;

    retVal =  CAN_setOptions(canHandle, &optionTLV, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN set option disable ECC DIAG failed [Error code %d]\n", errCode);
        return -1;
    }

    retVal = CAN_deinit(canHandle, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN deinit failed [Error code %d]\n", errCode);
        return -1;
    }

    return 0;
}

static int32_t dcanLoopbackTest()
{
    CAN_Handle              canHandle;
    CAN_MsgObjHandle        txMsgObjHandle;
    CAN_MsgObjHandle        rxMsgObjHandle;
    int32_t                 retVal = 0;
    int32_t                 errCode = 0;
    CAN_OptionTLV           optionTLV;
    uint8_t                 value;
    CAN_DCANMsgObjectStats  msgObjStats;

    gTxDoneFlag = 0;

    /* Initialize the DCAN parameters that need to be specified by the application */
    DCANAppInitParams(&appDcanCfgParams,
                      &appDcanTxCfgParams,
                      &appDcanRxCfgParams,
                      &appDcanTxData);

    /* Initialize the CAN driver */
    canHandle = CAN_init(&appDcanCfgParams, &errCode);
    if (canHandle == NULL)
    {
        System_printf ("Error: CAN Module Initialization failed [Error code %d]\n", errCode);
        return -1;
    }

    /* Set the desired bit rate based on input clock */
    retVal = DCANAppCalcBitTimeParams(DCAN_APP_INPUT_CLK / 1000000,
                                            DCAN_APP_BIT_RATE / 1000,
                                            DCAN_APP_SAMP_PT,
                                            DCAN_APP_PROP_DELAY,
                                            &appDcanBitTimeParams);
    if (retVal < 0)
    {
        System_printf ("Error: CAN Module bit time parameters are incorrect \n");
        return -1;
    }

    /* Configure the CAN driver */
    retVal = CAN_configBitTime (canHandle, &appDcanBitTimeParams, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN Module configure bit time failed [Error code %d]\n", errCode);
        return -1;
    }

    /* Setup the transmit message object */
    txMsgObjHandle = CAN_createMsgObject (canHandle, DCAN_TX_MSG_OBJ, &appDcanTxCfgParams, &errCode);
    if (txMsgObjHandle == NULL)
    {
        System_printf ("Error: CAN create Tx message object failed [Error code %d]\n", errCode);
        return -1;
    }

    /* Setup the receive message object */
    rxMsgObjHandle = CAN_createMsgObject (canHandle, DCAN_RX_MSG_OBJ, &appDcanRxCfgParams, &errCode);
    if (rxMsgObjHandle == NULL)
    {
        System_printf ("Error: CAN create Rx message object failed [Error code %d]\n", errCode);
        return -1;
    }

    /* Initialize the measurement counters */
    minRxTicks   = 0xFFFFFFFFU;
    maxRxTicks   = 0U;
    minTxTicks   = 0xFFFFFFFFU;
    maxTxTicks   = 0U;
    totalTxTicks = 0U;
    totalRxTicks = 0U;

    while (iterationCount != DCAN_APP_TEST_MESSAGE_COUNT)
    {
        /* Reset the counter: */
        Test_benchmarkStart(0);

        /* Send data over Tx message object */
        retVal = CAN_transmitData (txMsgObjHandle, &appDcanTxData, &errCode);
        if (retVal < 0)
        {
            System_printf ("Error: CAN transmit data for iteration %d failed [Error code %d]\n", iterationCount, errCode);
            return -1;
        }

        /* Stop the counter: */
        txTicks[iterationCount] = Test_benchmarkStop(0);

        /* Update the transmit statistics: */
        minTxTicks   = (minTxTicks < txTicks[iterationCount]) ? minTxTicks : txTicks[iterationCount];
        maxTxTicks   = (maxTxTicks > txTicks[iterationCount]) ? maxTxTicks : txTicks[iterationCount];
        totalTxTicks = totalTxTicks + txTicks[iterationCount];

        while (gTxDoneFlag == 0);
        gTxDoneFlag = 0;

        while (gRxDoneFlag == 0);
        gRxDoneFlag = 0;

        iterationCount++;
    }

    optionTLV.type = CAN_Option_DCAN_POWER_DOWN;
    optionTLV.length = sizeof(uint8_t);
    value = 1;
    optionTLV.value = (void*) &value;

    retVal =  CAN_setOptions(canHandle, &optionTLV, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN set option SLEEP failed [Error code %d]\n", errCode);
        return -1;
    }

    optionTLV.type = CAN_Option_DCAN_POWER_DOWN;
    optionTLV.length = sizeof(uint8_t);
    value = 0;
    optionTLV.value = (void*) &value;

    retVal =  CAN_setOptions(canHandle, &optionTLV, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN set option WAKEUP failed [Error code %d]\n", errCode);
        return -1;
    }

    System_printf("Debug: Number of iterations              : %d\n", iterationCount);
    System_printf("Debug: Number of messages transmitted    : %d\n", gTxPkts);
    System_printf("Debug: Number of messages received       : %d\n", gRxPkts);
    System_printf("Debug: Number of messages lost           : %d\n", msgLstErrCnt);
    System_printf("Debug: Number of data mismatch           : %d\n", dataMissMatchErrCnt);
    System_printf("Debug: Error Status Interrupt            : %d\n", gErrStatusInt);
    System_printf("\n\n");

    msgObjStats.handle = txMsgObjHandle;
    optionTLV.type = CAN_Option_DCAN_MSG_OBJECT_STATS;
    optionTLV.length = sizeof(CAN_DCANMsgObjectStats);
    optionTLV.value = (void*) &msgObjStats;

    retVal =  CAN_getOptions(canHandle, &optionTLV, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN get stats failed [Error code %d]\n", errCode);
        return -1;
    }

    System_printf("Debug: Message object number             : %d\n", msgObjStats.msgObjectNum);
    System_printf("Debug: Direction                         : %s\n", (msgObjStats.direction == 0) ? "Receive" : "Transmit");
    System_printf("Debug: Number of interrupts received     : %d\n", msgObjStats.interruptsRxed);
    System_printf("Debug: Number of messages processed      : %d\n", msgObjStats.messageProcessed);
    System_printf("\n\n");

    msgObjStats.handle = rxMsgObjHandle;
    retVal =  CAN_getOptions(canHandle, &optionTLV, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN get stats failed [Error code %d]\n", errCode);
        return -1;
    }

    System_printf("Debug: Message object number             : %d\n", msgObjStats.msgObjectNum);
    System_printf("Debug: Direction                         : %s\n", (msgObjStats.direction == 0) ? "Receive" : "Transmit");
    System_printf("Debug: Number of interrupts received     : %d\n", msgObjStats.interruptsRxed);
    System_printf("Debug: Number of messages processed      : %d\n", msgObjStats.messageProcessed);

    System_printf("Debug: Receive & Transmit Measurements\n");
    System_printf("Debug: Rx Min:%d Max: %d Average:%d ticks\n", minRxTicks, maxRxTicks, totalRxTicks/gTxPkts);
    System_printf("Debug: Tx Min:%d Max: %d Average:%d ticks\n", minTxTicks, maxTxTicks, totalTxTicks/gRxPkts);

    System_printf("\n\n");

    retVal = CAN_deleteMsgObject(txMsgObjHandle, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN delete Tx message object failed [Error code %d]\n", errCode);
        return -1;
    }

    retVal = CAN_deleteMsgObject(rxMsgObjHandle, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN delete Rx message object failed [Error code %d]\n", errCode);
        return -1;
    }

    retVal = CAN_deinit(canHandle, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN deinit failed [Error code %d]\n", errCode);
        return -1;
    }

    if ((msgLstErrCnt == 0) && (dataMissMatchErrCnt == 0))
    {
        if (testSelection == DCAN_APP_TEST_INTERNAL_LOOPBACK)
        {
            System_printf("Debug: Internal loopback testing for %d iterations Passed\n", iterationCount);
        }
        else
        {
            System_printf("Debug: External loopback testing for %d iterations Passed\n", iterationCount);
        }
    }
    else
    {
        if (testSelection == DCAN_APP_TEST_INTERNAL_LOOPBACK)
        {
            System_printf("Debug: Internal loopback testing for %d iterations Failed\n", iterationCount);
            retVal = -1;
        }
        else
        {
            System_printf("Debug: External loopback testing for %d iterations Failed\n", iterationCount);
            retVal = -1;
        }
    }
    return retVal;
}

static int32_t dcanTransmitTest()
{
    CAN_Handle              canHandle;
    CAN_MsgObjHandle        txMsgObjHandle;
    CAN_MsgObjHandle        rxMsgObjHandle;
    int32_t                 retVal = 0;
    int32_t                 errCode = 0;
    CAN_DCANMsgObjectStats  msgObjStats;
    CAN_OptionTLV           optionTLV;
    CAN_DCANErrorCounter    errCounter;

    /* Initialize the DCAN parameters that need to be specified by the application */
    DCANAppInitParams(&appDcanCfgParams,
                      &appDcanTxCfgParams,
                      &appDcanRxCfgParams,
                      &appDcanTxData);

    /* Initialize the CAN driver */
    canHandle = CAN_init(&appDcanCfgParams, &errCode);
    if (canHandle == NULL)
    {
        System_printf ("Error: CAN Module Initialization failed [Error code %d]\n", errCode);
        return -1;
    }

    /* Set the desired bit rate based on input clock */
    retVal = DCANAppCalcBitTimeParams(DCAN_APP_INPUT_CLK / 1000000,
                                            DCAN_APP_BIT_RATE / 1000,
                                            DCAN_APP_SAMP_PT,
                                            DCAN_APP_PROP_DELAY,
                                            &appDcanBitTimeParams);
    if (retVal < 0)
    {
        System_printf ("Error: CAN Module bit time parameters are incorrect \n");
        return -1;
    }

    /* Configure the CAN driver */
    retVal = CAN_configBitTime (canHandle, &appDcanBitTimeParams, &errCode);
    if (retVal < 0)
    {
        System_printf ("Error: CAN Module configure bit time failed [Error code %d]\n", errCode);
        return -1;
    }

    /* Setup the transmit message object */
    txMsgObjHandle = CAN_createMsgObject (canHandle, DCAN_TX_MSG_OBJ, &appDcanTxCfgParams, &errCode);
    if (txMsgObjHandle == NULL)
    {
        System_printf ("Error: CAN create Tx message object failed [Error code %d]\n", errCode);
        return -1;
    }

    /* Setup the receive message object */
    rxMsgObjHandle = CAN_createMsgObject (canHandle, DCAN_RX_MSG_OBJ, &appDcanRxCfgParams, &errCode);
    if (rxMsgObjHandle == NULL)
    {
        System_printf ("Error: CAN create Rx message object failed [Error code %d]\n", errCode);
        return -1;
    }

    while (1)
    {
        /* Send data over Tx message object */
        retVal = CAN_transmitData (txMsgObjHandle, &appDcanTxData, &errCode);
        if (retVal < 0)
        {
            System_printf ("Error: CAN transmit data for iteration %d failed [Error code %d]\n", iterationCount, errCode);
            return -1;
        }

        iterationCount++;

        if (gDisplayStats == 1)
        {
            gDisplayStats = 0;
            if (((msgLstErrCnt == 0) &&
                 (dataMissMatchErrCnt == 0)) && (retVal == 0))
            {
                System_printf("Debug: External transmit testing Passed\n");
            }
            else
            {
                System_printf("Debug: External transmit testing failed\n");
                retVal = -1;
            }

            System_printf("Debug: Number of iterations              : %d\n", iterationCount);
            System_printf("Debug: Number of messages transmitted    : %d\n", gTxPkts);
            System_printf("Debug: Number of messages received       : %d\n", gRxPkts);
            System_printf("Debug: Number of messages lost           : %d\n", msgLstErrCnt);
            System_printf("Debug: Error Status Interrupt            : %d\n", gErrStatusInt);
            System_printf("\n\n");

            msgObjStats.handle = txMsgObjHandle;
            optionTLV.type = CAN_Option_DCAN_MSG_OBJECT_STATS;
            optionTLV.length = sizeof(CAN_DCANMsgObjectStats);
            optionTLV.value = (void*) &msgObjStats;

            retVal =  CAN_getOptions(canHandle, &optionTLV, &errCode);
            if (retVal < 0)
            {
                System_printf ("Error: CAN get stats failed [Error code %d]\n", errCode);
            }

            System_printf("Debug: Message object number             : %d\n", msgObjStats.msgObjectNum);
            System_printf("Debug: Direction                         : %s\n", (msgObjStats.direction == 0) ? "Receive" : "Transmit");
            System_printf("Debug: Number of interrupts received     : %d\n", msgObjStats.interruptsRxed);
            System_printf("Debug: Number of messages processed      : %d\n", msgObjStats.messageProcessed);
            System_printf("\n\n");

            msgObjStats.handle = rxMsgObjHandle;
            retVal =  CAN_getOptions(canHandle, &optionTLV, &errCode);
            if (retVal < 0)
            {
                System_printf ("Error: CAN get stats failed [Error code %d]\n", errCode);
            }

            System_printf("Debug: Message object number             : %d\n", msgObjStats.msgObjectNum);
            System_printf("Debug: Direction                         : %s\n", (msgObjStats.direction == 0) ? "Receive" : "Transmit");
            System_printf("Debug: Number of interrupts received     : %d\n", msgObjStats.interruptsRxed);
            System_printf("Debug: Number of messages processed      : %d\n", msgObjStats.messageProcessed);
            System_printf("\n\n");

            optionTLV.type = CAN_Option_DCAN_ERROR_COUNTER;
            optionTLV.length = sizeof(CAN_DCANErrorCounter);
            optionTLV.value = (void*) &errCounter;

            retVal =  CAN_getOptions(canHandle, &optionTLV, &errCode);
            if (retVal < 0)
            {
                System_printf ("Error: CAN get error counter failed [Error code %d]\n", errCode);
            }

            System_printf("Debug: Receive passive error             : %d\n", errCounter.rxErrPassive);
            System_printf("Debug: Transmit Error Counter            : %d\n", errCounter.txErrCounter);
            System_printf("Debug: Receive Error Counter             : %d\n", errCounter.rxErrCounter);
        }
    }
}

/**************************************************************************
 *************************** Global Definitions ***************************
 **************************************************************************/

/**
 * @brief
 *  Global Variable for tracking information required by the SRR TI Design
 */
#pragma DATA_ALIGN(gSrrMSSMCB, 16);
Srr_MSS_MCB    gSrrMSSMCB;

/**************************************************************************
 *************************** Local Definitions ****************************
 **************************************************************************/
static void SRR_MSS_chirpIntCallback(uintptr_t arg);
static void SRR_MSS_frameStartIntCallback(uintptr_t arg);
static int32_t SRR_MSS_eventFxn(uint16_t msgId, uint16_t sbId, uint16_t sbLen, uint8_t *payload);
static void SRR_MSS_cfgFxn(MMWave_CtrlCfg* ptrCtrlCfg);
static void SRR_MSS_startFxn(MMWave_CalibrationCfg* ptrCalibrationCfg);
static void SRR_MSS_stopFxn(void);
static void SRR_MSS_initTask (UArg arg0, UArg arg1);
static void SRR_MSS_mmWaveCtrlTask (UArg arg0, UArg arg1);

#ifdef USE_LVDS_INTERFACE_FOR_OBJECT_DATA_TX
static int32_t SRR_MSS_configureStreaming();
static int32_t SRR_MSS_EDMAAllocateCBUFFChannel (CBUFF_EDMAInfo* ptrEDMAInfo, CBUFF_EDMAChannelCfg* ptrEDMACfg);
static void SRR_MSS_EDMAFreeCBUFFChannel(CBUFF_EDMAChannelCfg* ptrEDMACfg);
static EDMA_Handle SRR_MSS_openEDMA(uint8_t instance);
int32_t SRR_MSS_initEDMA(uint8_t instance);
static void SRR_MSS_edmaErrorCallbackFxn(EDMA_Handle handle, EDMA_errorInfo_t* errorInfo);
static void SRR_MSS_edmaTransferControllerErrorCallbackFxn(EDMA_Handle handle,
                                                    EDMA_transferControllerErrorInfo_t* errorInfo);

/*! @brief
 *  The global variable gwSwUserBuffer will be filled with the object data, and send over LVDS. The
 * size of thar array is determined by the largest message possible and is given by
 * Header, TLV (3 of them) + 'detected objects' +  cluster + trackers + parking Assist.*/
#pragma DATA_ALIGN(gSwUserBuffer, 32);
volatile uint16_t gSwUserBuffer[2048];
#endif
/**************************************************************************
 ********************** MSS SRR TI Design Functions ***********************
 **************************************************************************/

/**
 *  @b Description
 *  @n
 *      This is the callback function registered with the ADC Driver which is invoked
 *      when a chirp is available. This is executed in the ISR context.
 *     
 *  @param[in]  arg
 *      Application registered argument
 *
 *  @retval
 *      Not Applicable.
 */
static void SRR_MSS_chirpIntCallback(uintptr_t arg)
{
    gSrrMSSMCB.chirpInt++;
    gSrrMSSMCB.chirpIntcumSum++;
   
    /* The different subframes in the SRR configuration have different chirp sizes.
     * These need to be configured before the start of the next subframe, at the
     * end of the previous subframes last chirp. */
    if (gSrrMSSMCB.chirpInt == gSrrMSSMCB.numChirpsPerSubframe[gSrrMSSMCB.subframeId])
    {
  gSrrMSSMCB.subframeCntFromChirpInt++;
        gSrrMSSMCB.subframeId = gSrrMSSMCB.subframeId + 1;
        if (gSrrMSSMCB.subframeId == NUM_SUBFRAMES)
        {
            gSrrMSSMCB.subframeId = 0;
        }
        gSrrMSSMCB.chirpInt = 0;
    }
}

/**
 *  @b Description
 *  @n
 *      This is the callback function registered with the ADC Driver which is invoked
 *      when a frame is started. This is executed in the ISR context.
 *
 *  @param[in]  arg
 *      Application registered argument
 *
 *  @retval
 *      Not Applicable.
 */
static void SRR_MSS_frameStartIntCallback(uintptr_t arg)
{
    gSrrMSSMCB.frameStartToken++;
 gSrrMSSMCB.subframeCntFromFrameStart++;
    /* Check if the frames are coming correctly, and no chirps have been missed.   */
    if (gSrrMSSMCB.frameStartToken == 1)
    {
        if (gSrrMSSMCB.chirpInt == 0)
        {
            gSrrMSSMCB.frameStartToken = 0;
        }
        else
        {
            DebugP_assert (0);
        }
    }
}

/**
 *  @b Description
 *  @n
 *      Registered event function which is invoked when an event from the
 *      BSS is received.
 *
 *  @param[in]  msgId
 *      Message Identifier
 *  @param[in]  sbId
 *      Subblock identifier
 *  @param[in]  sbLen
 *      Length of the subblock
 *  @param[in]  payload
 *      Pointer to the payload buffer
 *
 *  @retval
 *      Always returns 0 [Continue passing the event to the peer domain]
 */
static int32_t SRR_MSS_eventFxn(uint16_t msgId, uint16_t sbId, uint16_t sbLen, uint8_t *payload)
{
    uint16_t asyncSB = RL_GET_SBID_FROM_UNIQ_SBID(sbId);

    /* Process the received message: */
    switch (msgId)
    {
        case RL_RF_ASYNC_EVENT_MSG:
        {
            /* Received Asychronous Message: */
            switch (asyncSB)
            {
                case RL_RF_AE_CPUFAULT_SB:
                {
                    /* Post event to datapath task notify BSS events */
                    //Event_post(gSrrMSSMCB.eventHandle, MMWDEMO_BSS_CPUFAULT_EVT);
                    break;
                }
                case RL_RF_AE_ESMFAULT_SB:
                {
                    /* Post event to datapath task notify BSS events */
                    //Event_post(gSrrMSSMCB.eventHandle, MMWDEMO_BSS_ESMFAULT_EVT);
                    break;
                }
                case RL_RF_AE_INITCALIBSTATUS_SB:
                {
                    /* This event should be handled by mmwave internally, ignore the event here */
                    break;
                }
                case RL_RF_AE_FRAME_TRIGGER_RDY_SB:
                {
                    break;
                }
                case RL_RF_AE_MON_TIMING_FAIL_REPORT_SB:
                {
                    break;
                }
                case RL_RF_AE_RUN_TIME_CALIB_REPORT_SB:
                {
                    break;
                }
                default:
                {
                    System_printf ("Error: Asynchronous Event SB Id %d not handled\n", asyncSB);
                    break;
                }
            }
            break;
        }
        default:
        {
           System_printf ("Error: Asynchronous message %d is NOT handled\n", msgId);
             break;
        }
    }
    return 0;
}

/**
 *  @b Description
 *  @n
 *      This is the application registered callback function which is invoked after
 *      the configuration has been used to configure the mmWave link and the BSS.
 *
 *  @param[in]  ptrCtrlCfg
 *      Pointer to the control configuration
 *
 *  @retval
 *      Not applicable
 */
static void SRR_MSS_cfgFxn(MMWave_CtrlCfg* ptrCtrlCfg)
{
    /* The SRR TI Design operates in MINIMAL mode and so the configuration
     * callback function is never invoked. The assertion will ensure that
     * this is never invoked */
    DebugP_assert (0);
}

/**
 *  @b Description
 *  @n
 *      Application registered callback function which is invoked the mmWave link on BSS
 *      has been started. This is applicable only for the XWR16xx. The BSS can be configured
 *      only by the MSS *or* DSS. The callback API is triggered on the remote execution
 *      domain (which did not configure the BSS)
 *
 *  @param[in]  ptrCalibrationCfg
 *      Pointer to the calibrat ion configuration
 *
 *  @retval
 *      Not applicable
 */
static void SRR_MSS_startFxn(MMWave_CalibrationCfg* ptrCalibrationCfg)
{
    /* Post an event to main data path task.
       This function in only called when mmwave_start() is called on DSS */
    gSrrMSSMCB.stats.datapathStartEvt ++;

    /* Post event to start is done */
    Event_post(gSrrMSSMCB.eventHandleNotify, MMWDEMO_DSS_START_COMPLETED_EVT);
}

/**
 *  @b Description
 *  @n
 *      This is the application registered callback function which is invoked after the
 *      has been stopped. This is applicable only for the XWR16xx. The BSS can be configured
 *      only by the MSS *or* DSS. The callback API is triggered on the remote execution
 *      mmWave link on BSS has been stopped.
 *
 *  @retval
 *      Not applicable
 */
static void SRR_MSS_stopFxn(void)
{
      /* Possible sceanarios:
       1. CLI sensorStop command triggers mmwave_stop() to be called from MSS
       2. In case of Error, mmwave_stop() will be triggered either from MSS or DSS
     */
    gSrrMSSMCB.stats.datapathStopEvt ++;
}

/**
 *  @b Description
 *  @n
 *      Application registered callback function which is invoked the mmWave link on BSS
 *      has been opened.
 *
 *  @param[in]  ptrOpenCfg
 *      Pointer to the open configuration
 *
 *  @retval
 *      Not applicable
 */
static void SRR_MSS_openFxn(MMWave_OpenCfg* ptrOpenCfg)
{
    return;
}


/**
 *  @b Description
 *  @n
 *      Application registered callback function which is invoked the mmWave link on BSS
 *      has been closed.
 *
 *  @retval
 *      Not applicable
 */
static void SRR_MSS_closeFxn(void)
{
    return;
}

/**
 *  @b Description
 *  @n
 *      Function to send a message to peer through Mailbox virtural channel
 *
 *  @param[in]  message
 *      Pointer to the MMW demo message. 
 *
 *  @retval
 *      Success    - 0
 *      Fail       < -1
 */
int32_t MmwDemo_mboxWrite(MmwDemo_message     * message)
{
    int32_t                  retVal = -1;
   
    retVal = Mailbox_write (gSrrMSSMCB.peerMailbox, (uint8_t*)message, sizeof(MmwDemo_message));
    if (retVal == sizeof(MmwDemo_message))
    {
        retVal = 0;
    }
    return retVal;
}

/**
 *  @b Description
 *  @n
 *      The Task is used to handle  the mmw demo messages received from
 *      Mailbox virtual channel. 
 *
 *  @param[in]  arg0
 *      arg0 of the Task. Not used
 *  @param[in]  arg1
 *      arg1 of the Task. Not used
 *
 *  @retval
 *      Not Applicable.
 */
static void MmwDemo_mboxReadTask(UArg arg0, UArg arg1)
{
    MmwDemo_message      message;
    int32_t              retVal = 0;
   
    /* wait for new message and process all the messsages received from the peer */
    while(1)
    {
        Semaphore_pend(gSrrMSSMCB.mboxSemHandle, BIOS_WAIT_FOREVER);
       
        /* Read the message from the peer mailbox: We are not trying to protect the read
         * from the peer mailbox because this is only being invoked from a single thread */
        retVal = Mailbox_read(gSrrMSSMCB.peerMailbox, (uint8_t*)&message, sizeof(MmwDemo_message));
        if (retVal < 0)
        {
            /* Error: Unable to read the message. Setup the error code and return values */
            System_printf ("Error: Mailbox read failed [Error code %d]\n", retVal);
        }
        else if (retVal == 0)
        {
            /* We are done: There are no messages available from the peer execution domain. */
            continue;
        }
        else
        {
            /* Flush out the contents of the mailbox to indicate that we are done with the message. This will
             * allow us to receive another message in the mailbox while we process the received message. */
            Mailbox_readFlush (gSrrMSSMCB.peerMailbox);

            /* Process the received message: */
            switch (message.type)
            {
                case MMWDEMO_DSS2MSS_DETOBJ_READY:
                    /* Got detected objects , to be shipped out shipped out through UART */
#ifdef USE_LVDS_INTERFACE_FOR_OBJECT_DATA_TX
                    {
                        int32_t errCode;
                        volatile uint32_t totalPacketLen = 0;
                        uint32_t itemIdx;
                        uint8_t *swUserBuffer = (uint8_t *)&gSwUserBuffer[0];

                        /* header */
                        memcpy(&swUserBuffer[totalPacketLen], (uint8_t*)&message.body.detObj.header, sizeof(MmwDemo_output_message_header));
                        totalPacketLen = sizeof(MmwDemo_output_message_header);
                       
                        /* TLVs */
                        for (itemIdx = 0;  itemIdx < message.body.detObj.header.numTLVs; itemIdx++)
                        {
                            memcpy(&swUserBuffer[totalPacketLen], (uint8_t*)&message.body.detObj.tlv[itemIdx], sizeof(MmwDemo_output_message_tl));
                       
                            totalPacketLen += sizeof(MmwDemo_output_message_tl);
                           
                            memcpy(&swUserBuffer[totalPacketLen],
                                   (uint8_t*)SOC_translateAddress(message.body.detObj.tlv[itemIdx].address,
                                   SOC_TranslateAddr_Dir_FROM_OTHER_CPU,NULL), message.body.detObj.tlv[itemIdx].length);
                           
                            totalPacketLen += message.body.detObj.tlv[itemIdx].length;
                        }

                        DebugP_assert(totalPacketLen < sizeof(gSwUserBuffer));
                       
                        /* Deactivate the hardware session */
                        DebugP_assert (CBUFF_deactivateSession (gSrrMSSMCB.swSessionHandle, &errCode) == 0);

                        /* Activate the hardware session */
                        DebugP_assert (CBUFF_activateSession (gSrrMSSMCB.swSessionHandle, &errCode) == 0);
                    }
#else
                    {
                        uint32_t totalPacketLen;
                        uint32_t numPaddingBytes;
                        uint32_t itemIdx;

                        /* Send header */
                        totalPacketLen = sizeof(MmwDemo_output_message_header);
                        UART_writePolling (gSrrMSSMCB.loggingUartHandle,
                                           (uint8_t*)&message.body.detObj.header,
                                           sizeof(MmwDemo_output_message_header));

                        /* Send TLVs */
                        for (itemIdx = 0;  itemIdx < message.body.detObj.header.numTLVs; itemIdx++)
                        {
                            UART_writePolling (gSrrMSSMCB.loggingUartHandle,
                                               (uint8_t*)&message.body.detObj.tlv[itemIdx],
                                               sizeof(MmwDemo_output_message_tl));
                            UART_writePolling (gSrrMSSMCB.loggingUartHandle,
                                               (uint8_t*)SOC_translateAddress(message.body.detObj.tlv[itemIdx].address,
                                                                              SOC_TranslateAddr_Dir_FROM_OTHER_CPU,NULL),
                                               message.body.detObj.tlv[itemIdx].length);
                            totalPacketLen += sizeof(MmwDemo_output_message_tl) + message.body.detObj.tlv[itemIdx].length;
                        }

                        /* Send padding to make total packet length multiple of MMWDEMO_OUTPUT_MSG_SEGMENT_LEN */
                        numPaddingBytes = MMWDEMO_OUTPUT_MSG_SEGMENT_LEN - (totalPacketLen & (MMWDEMO_OUTPUT_MSG_SEGMENT_LEN-1));
                        if (numPaddingBytes<MMWDEMO_OUTPUT_MSG_SEGMENT_LEN)
                        {
                            uint8_t padding[MMWDEMO_OUTPUT_MSG_SEGMENT_LEN];
                            /*DEBUG:*/ memset(&padding, 0xf, MMWDEMO_OUTPUT_MSG_SEGMENT_LEN);
                            UART_writePolling (gSrrMSSMCB.loggingUartHandle, padding, numPaddingBytes);
                        }
                    }
#endif
                    /* Send a message to MSS to log the output data */
                    memset((void *)&message, 0, sizeof(MmwDemo_message));

                    message.type = MMWDEMO_MSS2DSS_DETOBJ_SHIPPED;
                               
                    retVal = MmwDemo_mboxWrite(&message);
                   
                    if (retVal != 0)
                    {
                        System_printf ("Error: Mailbox send message id=%d failed \n", message.type);
                    }

                    break;
               
                case MMWDEMO_DSS2MSS_ASSERT_INFO:
                    /* Send the received DSS assert info through CLI */
                    CLI_write ("DSS Exception: %s, line %d.\n", message.body.assertInfo.file,
                        message.body.assertInfo.line);
                    break;
                default:
                {
                    /* Message not support */
                    System_printf ("Error: unsupport Mailbox message id=%d\n", message.type);
                    break;
                }
            }
        }
    }
}

/**
 *  @b Description
 *  @n
 *      This function is a callback funciton that invoked when a message is received from the peer.
 *
 *  @param[in]  handle
 *      Handle to the Mailbox on which data was received
 *  @param[in]  peer
 *      Peer from which data was received
 
 *  @retval
 *      Not Applicable.
 */
void MmwDemo_mboxCallback
(
    Mbox_Handle  handle,
    Mailbox_Type    peer
)
{
    /* Message has been received from the peer endpoint. Wakeup the mmWave thread to process
     * the received message. */
    Semaphore_post (gSrrMSSMCB.mboxSemHandle);
}


/**
 *  @b Description
 *  @n
 *      This is the task which provides an execution context for
 *      the mmWave control module.
 *
 *  @param[in]  arg0
 *      Argument0 with which the task was created
 *  @param[in]  arg1
 *      Argument1 with which the task was created
 *
 *  @retval
 *      Not Applicable.
 */
static void SRR_MSS_mmWaveCtrlTask (UArg arg0, UArg arg1)
{
    int32_t errCode;

    while (1)
    {

        /* Execute the mmWave control module: */
        if (MMWave_execute (gSrrMSSMCB.ctrlHandle, &errCode) < 0)
        {
            System_printf ("Error: mmWave control execution failed [Error code %d]\n", errCode);
        }
    }
}

/**
 *  @b Description
 *  @n
 *      Callback function invoked when the GPIO switch is pressed.
 *      This is invoked from interrupt context.
 *
 *  @param[in]  index
 *      GPIO index configured as input
 *
 *  @retval
 *      Not applicable
 */
static void SRR_MSS_switchPressFxn(unsigned int index)
{
}

/**
 *  @b Description
 *  @n
 *      The task is used to process data path events
 *      control task
 *
 *  @retval
 *      Not Applicable.
 */
void SRR_MSS_mssProcessDataPathTask(UArg arg0, UArg arg1)
{
    UInt          event = 0;

    /**********************************************************************
     * Setup the PINMUX:
     * - GPIO Input : Configure pin J13 as GPIO_1 input
     * - GPIO Output: Configure pin K13 as GPIO_2 output
     **********************************************************************/
    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINJ13_PADAC, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINJ13_PADAC, SOC_XWR16XX_PINJ13_PADAC_GPIO_1);
    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINK13_PADAZ, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINK13_PADAZ, SOC_XWR16XX_PINK13_PADAZ_GPIO_2);

    /**********************************************************************
     * Setup the SW1 switch on the EVM connected to GPIO_1
     * - This is used as an input
     * - Enable interrupt to be notified on a switch press
     **********************************************************************/
    GPIO_setConfig (SOC_XWR16XX_GPIO_1, GPIO_CFG_INPUT | GPIO_CFG_IN_INT_RISING | GPIO_CFG_IN_INT_LOW);
    GPIO_setCallback (SOC_XWR16XX_GPIO_1, SRR_MSS_switchPressFxn);
    GPIO_enableInt (SOC_XWR16XX_GPIO_1);

    /**********************************************************************
     * Setup the DS3 LED on the EVM connected to GPIO_2
     **********************************************************************/
    GPIO_setConfig (SOC_XWR16XX_GPIO_2, GPIO_CFG_OUTPUT);

    System_printf ("Debug: Data Path management main loop. \n");
    /* Data Path management task Main loop */
    while (1)
    {
        event = Event_pend(gSrrMSSMCB.eventHandle,
                          Event_Id_NONE,
                          MMWDEMO_CLI_EVENTS | MMWDEMO_BSS_FAULT_EVENTS,
                          BIOS_WAIT_FOREVER);

        /************************************************************************
         * BSS event:: CPU fault
         ************************************************************************/
        if(event & MMWDEMO_BSS_CPUFAULT_EVT)
        {
            break;
        }

        /************************************************************************
         * BSS event:: ESM fault
         ************************************************************************/
        if(event & MMWDEMO_BSS_ESMFAULT_EVT)
        {
            break;
        }
    }

    System_printf("Debug: MMWDemoDSS Data path exit\n");
}


/**
 *  @b Description
 *  @n
 *      MSS Initialization Task which initializes the various
 *      components in the MSS subsystem.
 *
 *  @param[in]  arg0
 *      Argument0 with which the task was created
 *  @param[in]  arg1
 *      Argument1 with which the task was created
 *
 *  @retval
 *      Not Applicable.
 */
static void SRR_MSS_initTask (UArg arg0, UArg arg1)
{
    int32_t                 errCode;
    MMWave_InitCfg          initCfg;
 UART_Params             uartParams;
    Task_Params             taskParams;
    SOC_SysIntListenerCfg   listenerCfg;
 Semaphore_Params    semParams;
    Mailbox_Config      mboxCfg;
   /* Debug Message: */
    System_printf("Debug: Launched the Initialization Task\n");

    /* Initialize the platform */
    int32_t retVal = PlatformInit();
    if (retVal < 0)
    {
        System_printf("Error: Unable to initialize platform CAN\n");
        BIOS_exit(0);
    }
    /*****************************************************************************
     * Initialize the mmWave SDK components:
     *****************************************************************************/
    /* Pinmux setting */

    /* Setup the PINMUX to bring out the UART-1 */
    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINN5_PADBE, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);   
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINN5_PADBE, SOC_XWR16XX_PINN5_PADBE_MSS_UARTA_TX);
    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINN4_PADBD, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);   
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINN4_PADBD, SOC_XWR16XX_PINN4_PADBD_MSS_UARTA_RX);

    /* Setup the PINMUX to bring out the UART-3 */
    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINF14_PADAJ, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINF14_PADAJ, SOC_XWR16XX_PINF14_PADAJ_MSS_UARTB_TX);

    /* Setup the PINMUX to bring out the DSS UART */
    Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINP8_PADBM, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
    Pinmux_Set_FuncSel(SOC_XWR16XX_PINP8_PADBM, SOC_XWR16XX_PINP8_PADBM_DSS_UART_TX);

    /* Initialize the UART */
    UART_init();

 /* Initialize the GPIO */
    GPIO_init();
   
    /* Initialize the Mailbox */
    Mailbox_init(MAILBOX_TYPE_MSS);

 /* Open UART Driver: */
    UART_Params_init(&uartParams);
    uartParams.clockFrequency = MSS_SYS_VCLK;
    uartParams.baudRate       = 115200;
    uartParams.isPinMuxDone   = 1;

    /* Open the Command UART Instance */
    gSrrMSSMCB.commandUartHandle = UART_open(0, &uartParams);
    if (gSrrMSSMCB.commandUartHandle == NULL)
    {
         System_printf("Error: Unable to open the Command UART Instance\n");
        return;
    }

  /* Setup the default UART Parameters */
    UART_Params_init(&uartParams);
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.clockFrequency = MSS_SYS_VCLK;
    uartParams.baudRate       = 115200*8;
    uartParams.isPinMuxDone   = 1U;

    /* Open the Logging UART Instance: */
    gSrrMSSMCB.loggingUartHandle = UART_open(1, &uartParams);
    if (gSrrMSSMCB.loggingUartHandle == NULL)
    {
        System_printf("Error: MMWDemoMSS Unable to open the Logging UART Instance\n");
        return;
    }

 /*****************************************************************************
     * Creating communication channel between MSS & DSS
     *****************************************************************************/

    /* Create a binary semaphore which is used to handle mailbox interrupt. */
    Semaphore_Params_init(&semParams);
    semParams.mode             = Semaphore_Mode_BINARY;
    gSrrMSSMCB.mboxSemHandle = Semaphore_create(0, &semParams, NULL);

    /* Setup the default mailbox configuration */
    Mailbox_Config_init(&mboxCfg);

    /* Setup the configuration: */
    mboxCfg.chType       = MAILBOX_CHTYPE_MULTI;
    mboxCfg.chId         = MAILBOX_CH_ID_0;
    mboxCfg.writeMode    = MAILBOX_MODE_BLOCKING;
    mboxCfg.readMode     = MAILBOX_MODE_CALLBACK;
    mboxCfg.readCallback = &MmwDemo_mboxCallback;

    /* Initialization of Mailbox Virtual Channel  */
    gSrrMSSMCB.peerMailbox = Mailbox_open(MAILBOX_TYPE_DSS, &mboxCfg, &errCode);
    if (gSrrMSSMCB.peerMailbox == NULL)
    {
        /* Error: Unable to open the mailbox */
        System_printf("Error: Unable to open the Mailbox to the DSS [Error code %d]\n", errCode);
        return;
    }

    /* Create task to handle mailbox messages */
    Task_Params_init(&taskParams);
    taskParams.stackSize = 16*1024;
    Task_create(MmwDemo_mboxReadTask, &taskParams, NULL);
 
 /* Register Chirp Available Listener */
    memset ((void*)&listenerCfg, 0, sizeof(SOC_SysIntListenerCfg));
    listenerCfg.systemInterrupt   = SOC_XWR16XX_MSS_CHIRP_AVAIL_IRQ;
    listenerCfg.listenerFxn       = SRR_MSS_chirpIntCallback;
    listenerCfg.arg               = 0;
    gSrrMSSMCB.chirpIntHandle = SOC_registerSysIntListener (gSrrMSSMCB.socHandle, &listenerCfg, &errCode);
    if (gSrrMSSMCB.chirpIntHandle == NULL)
    {
        System_printf ("Error: Unable to register the Chirp Available Listener [Error code %d]\n", errCode);
        return;
    }

 /* Register Frame Start Listener */
    memset ((void*)&listenerCfg, 0, sizeof(SOC_SysIntListenerCfg));
    listenerCfg.systemInterrupt   = SOC_XWR16XX_MSS_FRAME_START_INT;
    listenerCfg.listenerFxn       = SRR_MSS_frameStartIntCallback;
    listenerCfg.arg               = 0;
    gSrrMSSMCB.frameStartIntHandle = SOC_registerSysIntListener (gSrrMSSMCB.socHandle, &listenerCfg, &errCode);

    if (gSrrMSSMCB.frameStartIntHandle == NULL)
    {
        System_printf("Error: Unable to register the Frame start Listener [Error code %d]\n", errCode);
        return ;
    }

    /*****************************************************************************
     * Initialize the mmWave module:
     *****************************************************************************/
    memset ((void *)&initCfg, 0, sizeof(MMWave_InitCfg));

    /* Populate the initialization configuration:
     * The MMWAve is configured in minimal isolation mode. */
    initCfg.domain                      = MMWave_Domain_MSS;
    initCfg.socHandle                   = gSrrMSSMCB.socHandle;
    initCfg.eventFxn                    = &SRR_MSS_eventFxn;
    initCfg.cfgMode                     = MMWave_ConfigurationMode_MINIMAL;
    initCfg.executionMode               = MMWave_ExecutionMode_ISOLATION;
    initCfg.linkCRCCfg.useCRCDriver     = 1U;
    initCfg.linkCRCCfg.crcChannel       = CRC_Channel_CH1;
    initCfg.cooperativeModeCfg.cfgFxn   = &SRR_MSS_cfgFxn;
    initCfg.cooperativeModeCfg.startFxn = &SRR_MSS_startFxn;
    initCfg.cooperativeModeCfg.stopFxn  = &SRR_MSS_stopFxn;
    initCfg.cooperativeModeCfg.openFxn  = &SRR_MSS_openFxn;
    initCfg.cooperativeModeCfg.closeFxn = &SRR_MSS_closeFxn;
   
    /* Initialize and setup the mmWave Control module */
    gSrrMSSMCB.ctrlHandle = MMWave_init (&initCfg, &errCode);
    if (gSrrMSSMCB.ctrlHandle == NULL)
    {
        /* Error: Unable to initialize the mmWave control module */
        System_printf ("Error: mmWave Control Initialization failed [Error code %d]\n", errCode);
        return;
    }
    System_printf ("Debug: Initialized the mmWave module\n");

    /*****************************************************************************
     * Synchronize the mmWave module:
     *****************************************************************************/
    while (1)
    {
        int32_t syncStatus;

        /*--------------------------------------------------------------*/
        /*--------------------------------------------------------------*/
        System_printf("Debug: parity testing\n");
        retVal = dcanParityTest();
        if (retVal == -1)
            System_printf("Debug: parity testing FAIL\n");
        else
            System_printf("Debug: parity testing PASS\n");

        /*--------------------------------------------------------------*/
        /*--------------------------------------------------------------*/

        /* Get the synchronization status: */
        syncStatus = MMWave_sync (gSrrMSSMCB.ctrlHandle, &errCode);
        if (syncStatus < 0)
        {
            /* Error: Unable to synchronize the mmWave control module */
            System_printf ("Error: mmWave Control Synchronization failed [Error code %d]\n", errCode);
            return;
        }
        if (syncStatus == 1)
        {
            /* Synchronization acheived: */
            break;
        }
        /* Sleep and poll again: */
        Task_sleep(1);
    }
   
    System_printf ("Debug: Synchronized the mmWave module\n");

    #ifdef SUBFRAME_CONF_SRR_USRR
        gSrrMSSMCB.numChirpsPerSubframe[0] = SUBFRAME_SRR_NUM_CHIRPS_TOTAL;
        gSrrMSSMCB.numChirpsPerSubframe[1] = SUBFRAME_USRR_NUM_CHIRPS_TOTAL;
    #else
 #ifdef SUBFRAME_CONF_SRR
        gSrrMSSMCB.numChirpsPerSubframe[0] = SUBFRAME_SRR_NUM_CHIRPS_TOTAL;
 #endif
 #ifdef SUBFRAME_CONF_USRR
        gSrrMSSMCB.numChirpsPerSubframe[0] = SUBFRAME_USRR_NUM_CHIRPS_TOTAL;
 #endif
 #endif
   
#ifdef USE_LVDS_INTERFACE_FOR_OBJECT_DATA_TX
    /* Configure the LVDS streaming interface.*/
    {
        int32_t streamConfiguration = SRR_MSS_configureStreaming() ;
   
        if (streamConfiguration != 0)
        {
            System_printf ("Error: Unable to activate the Streaming Session [Error code %d]\n", streamConfiguration);
               
            DebugP_assert (0);  
        }
    }
#endif

    /*****************************************************************************
     * Launch the mmWave control execution task
     * - This should have a higher priroity than any other task which uses the
     *   mmWave control API
     *****************************************************************************/
    Task_Params_init(&taskParams);
    taskParams.priority  = 6;
    taskParams.stackSize = 3*1024;
    Task_create(SRR_MSS_mmWaveCtrlTask, &taskParams, NULL);

    /*****************************************************************************
     * Setup the CLI
     *****************************************************************************/
    SRR_MSS_CLIInit ();
}

/**
 *  @b Description
 *  @n
 *      Entry point into the MSS TI Design
 *
 *  @retval
 *      Not Applicable.
 */
int32_t main (void)
{
    Task_Params     taskParams;
    int32_t         errCode;
    SOC_Cfg         socCfg;

    /* Initialize the ESM: Dont clear errors as TI RTOS does it */
    ESM_init(0U);

    /* Initialize the global variables */
    memset ((void*)&gSrrMSSMCB, 0, sizeof(Srr_MSS_MCB));

    /* Initialize the SOC configuration: */
    memset ((void *)&socCfg, 0, sizeof(SOC_Cfg));

    /* Populate the SOC configuration: */
    socCfg.clockCfg = SOC_SysClock_INIT;

    /* Initialize the SOC Module: This is done as soon as the application is started
     * to ensure that the MPU is correctly configured. */
    gSrrMSSMCB.socHandle = SOC_init (&socCfg, &errCode);
    if (gSrrMSSMCB.socHandle == NULL)
    {
        System_printf ("Error: SOC Module Initialization failed [Error code %d]\n", errCode);
        return -1;
    }

    /* Initialize the Task Parameters. */
    Task_Params_init(&taskParams);
 taskParams.priority = 3;
    Task_create(SRR_MSS_initTask, &taskParams, NULL);

    /* Start BIOS */
    BIOS_start();
    return 0;
}

#ifdef USE_LVDS_INTERFACE_FOR_OBJECT_DATA_TX

/**
 *  @b Description
 *  @n
 *      The function is used to configure the CBUFF/LVDS Streaming
 *
 *  @param[in]  ptrDataPathObj
 *      Handle to data Path object
 *
 *  @retval
 *      Success  - 0
 *  @retval
 *      Error    - <0
 */
static int32_t SRR_MSS_configureStreaming()
{
    CBUFF_InitCfg       initCfg;
    CBUFF_SessionCfg    sessionCfg;
    rlDevHsiClk_t       hsiClkgs;
    int32_t             errCode;
    int32_t             retVal = -1;

    /* Initialize the CBUFF Initialization configuration: */
    memset ((void *)&initCfg, 0, sizeof(CBUFF_InitCfg));

    /* Populate the configuration: */
    initCfg.socHandle                = gSrrMSSMCB.socHandle;
    initCfg.enableECC                = 0U;
    initCfg.crcEnable                = 1U;
    initCfg.maxSessions              = 1U;
    initCfg.enableDebugMode          = false;
    initCfg.interface                = CBUFF_Interface_LVDS;
    initCfg.u.lvdsCfg.crcEnable      = 0U;
    initCfg.u.lvdsCfg.msbFirst       = 1U;
    initCfg.u.lvdsCfg.lvdsLaneEnable = 0x3U;
    initCfg.u.lvdsCfg.ddrClockMode   = 1U;
    initCfg.u.lvdsCfg.ddrClockModeMux= 1U;

   
    /*****************************************************************************
     * Initialize EDMA driver
     *****************************************************************************/
    if (SRR_MSS_initEDMA(CBUFF_EDMA_INSTANCE) < 0)
    {
        return -1;
    }   

    /*****************************************************************************
     * Open EDMA driver:
     *****************************************************************************/
    if( (gSrrMSSMCB.dmaHandle = SRR_MSS_openEDMA(CBUFF_EDMA_INSTANCE)  )== NULL)
    {
        return -2;
    }
       
    /* Translate the data format from the mmWave link to the CBUFF: */
    /* 16bit Data Output Format: */
    initCfg.outputDataFmt = CBUFF_OutputDataFmt_16bit;

    /* Initialize the CBUFF Driver: */
    gSrrMSSMCB.cbuffHandle = CBUFF_init (&initCfg, &errCode);
    if (gSrrMSSMCB.cbuffHandle == NULL)
    {
        /* Error: Unable to initialize the CBUFF; report the error */
        System_printf ("Error: CBUFF Driver initialization failed [Error code %d]\n", errCode);
        goto exit;
    }


    /********************************************************************************
     * Software Triggered Session:
     ********************************************************************************/
    {
        /* Initialize the session configuration: */
        memset ((void*)&sessionCfg, 0, sizeof(CBUFF_SessionCfg));

        /* Populate the configuration: */
        sessionCfg.executionMode                     = CBUFF_SessionExecuteMode_SW;
        sessionCfg.edmaHandle                        = gSrrMSSMCB.dmaHandle;
        sessionCfg.allocateEDMAChannelFxn            = SRR_MSS_EDMAAllocateCBUFFChannel;
        sessionCfg.freeEDMAChannelFxn                = SRR_MSS_EDMAFreeCBUFFChannel;
        sessionCfg.frameDoneCallbackFxn              = NULL;
        sessionCfg.dataType                          = CBUFF_DataType_REAL;
        sessionCfg.u.swCfg.headerMode                = CBUFF_HeaderMode_NONE;
        sessionCfg.u.swCfg.userBufferInfo[0].size    = sizeof(gSwUserBuffer)/2;
        sessionCfg.u.swCfg.userBufferInfo[0].address = (uint32_t)&gSwUserBuffer[0];

        /* Create the session: */
        gSrrMSSMCB.swSessionHandle = CBUFF_createSession (gSrrMSSMCB.cbuffHandle, &sessionCfg, &errCode);
        if (gSrrMSSMCB.swSessionHandle == NULL)
        {
            System_printf ("Error: Unable to create the CBUFF Session [Error code %d]\n", errCode);
            retVal = -3;
            goto exit;
        }
    }

    /*************************************************************************************
     * Setup the HSI Clock through the mmWave Link:
     *************************************************************************************/
    memset ((void*)&hsiClkgs, 0, sizeof(rlDevHsiClk_t));

    /* Setup the HSI Clock as per the Radar Interface Document: This is set to 600Mhtz DDR Mode */
    hsiClkgs.hsiClk = 0x9;

    /* Setup the HSI in the radar link: */
    retVal = rlDeviceSetHsiClk(RL_DEVICE_MAP_CASCADED_1, &hsiClkgs);
    if (retVal != RL_RET_CODE_OK)
    {
        /* Error: Unable to set the HSI clock */
        System_printf ("Error: Setting up the HSI Clock in BSS Failed [Error %d]\n", retVal);
        goto exit;
    }

    {
        /******************************************************************************
         * ----------------------------------------------------------------------------
         * Use Case 3: Hardware sessions is DISABLED and Software session is ENABLED
         * ----------------------------------------------------------------------------
         *    1) Activate SW Session
         *    2) Frame Done on SW Session
         *       -> Do nothing.
         *  This is to simulate a use case where only the application debug data is
         *  being streamed out. So we kaunch the software session trigger task which
         *  will send out the data periodically. Activate the software session
         ******************************************************************************/
        if (CBUFF_activateSession (gSrrMSSMCB.swSessionHandle, &errCode) < 0)
        {
            System_printf ("Error: Unable to activate the CBUFF Session [Error code %d]\n", errCode);
            retVal = -4;
            goto exit;
        }

       
    }
   
    /* Setup the return value as the CBUFF streaming has been configured successfully */
    retVal = 0;

exit:
    return retVal;
}

/**
 *  @b Description
 *  @n
 *      This is the registered CBUFF EDMA channel allocation function which allocates
 *      EDMA channels for HW Triggered sessions
 *
 *  @retval
 *      Success -   0
 *  @retval
 *      Error   -   <0
 */
static int32_t SRR_MSS_EDMAAllocateCBUFFChannel (CBUFF_EDMAInfo* ptrEDMAInfo, CBUFF_EDMAChannelCfg* ptrEDMACfg)
{
    /* Use the DMA Information to perform the CBUFF EDMA allocations */
    if (ptrEDMAInfo->dmaNum == 0U)
    {
        ptrEDMACfg->chainChannelsId = SRR_CBUFF_EDMA_CH;
        ptrEDMACfg->shadowLinkChannelsId = SRR_CBUFF_EDMA_SHADOW_CH;
    }
    else
    {
        /* Error: SRR only supports a single session (i.e. DMA-0)*/
        DebugP_assert (0);
    }
    return 0;
}


/**
 *  @b Description
 *  @n
 *      This is the registered CBUFF EDMA channel free function which frees allocated
 *      EDMA channels for HW Triggered sessions
 *
 *  @retval
 *      Not applicable
 */
static void SRR_MSS_EDMAFreeCBUFFChannel(CBUFF_EDMAChannelCfg* ptrEDMACfg)
{
   
    return;
   
}


/**
 *  @b Description
 *  @n
 *      Open EDMA driver Instance for ADCBUF data buffer copy.
 *
 *  @param[in]  instance
 *      EDMA driver instance.
 *
 *  @retval
 *      Success     - EDMA handle
 *      Fail        - NULL pointer
 */
static EDMA_Handle SRR_MSS_openEDMA(uint8_t instance)
{
    EDMA_errorInfo_t              EDMAErrorInfo;
    EDMA_transferControllerErrorInfo_t EDMATransferControllerErrorInfo;
    EDMA_Handle                   EdmaHandle = NULL;
    EDMA_instanceInfo_t           instanceInfo;
    EDMA_errorConfig_t            errorConfig;
    int32_t                       retVal = 0;

    memset(&EDMAErrorInfo, 0, sizeof(EDMAErrorInfo));
    memset(&EDMATransferControllerErrorInfo, 0, sizeof(EDMATransferControllerErrorInfo));

    /* Open the EDMA Instance */
    EdmaHandle = EDMA_open(instance, &retVal, &instanceInfo);
    if (EdmaHandle == NULL)
    {
        System_printf("Error: Unable to open the edma Instance(%d), errorCode = %d\n",instance, retVal);
        return NULL;
    }

    /* Configurate EDMA Error Monitor */
    errorConfig.isConfigAllEventQueues = true;
    errorConfig.isConfigAllTransferControllers = true;
    errorConfig.isEventQueueThresholdingEnabled = true;
    errorConfig.eventQueueThreshold = EDMA_EVENT_QUEUE_THRESHOLD_MAX;
    errorConfig.isEnableAllTransferControllerErrors = true;
    errorConfig.callbackFxn = SRR_MSS_edmaErrorCallbackFxn;
    errorConfig.transferControllerCallbackFxn = SRR_MSS_edmaTransferControllerErrorCallbackFxn;
    if ((retVal = EDMA_configErrorMonitoring(EdmaHandle, &errorConfig)) != EDMA_NO_ERROR)
    {
        System_printf("Debug: EDMA_configErrorMonitoring() failed with errorCode = %d\n", retVal);
        return NULL;
    }

    return EdmaHandle;
}


/**
 *  @b Description
 *  @n
 *      EDMA driver instance Initialization. Application is responsible for EDMA instance
 *  management.
 *
 *  @param[in]  instance
 *      EDMA driver instance.
 *
 *  @retval
 *      Success     - 0
 *      Fail        - -1
 */
int32_t SRR_MSS_initEDMA(uint8_t instance)
{
    int32_t    retVal = 0;

    retVal = EDMA_init(instance);
    if (retVal != EDMA_NO_ERROR)
    {
        System_printf ("Debug: EDMA instance %d initialization returned error %d\n", instance, retVal);
        return -1;
    }
    System_printf ("Debug: EDMA instance %d has been initialized\n", instance);
    return 0;
}


/**
 *  @b Description
 *  @n
 *      Call back function for EDMA CC (Channel controller) error as per EDMA API.
 *      Declare fatal error if happens, the output errorInfo can be examined if code
 *      gets trapped here.
 *
 *  @param[in]  handle
 *      EDMA driver instance Handle
 *  @param[in]  errorInfo
 *      EDMA Channle id used to copy data buffer
 *
 *  @retval
 *      None
 */
static void SRR_MSS_edmaErrorCallbackFxn
(
    EDMA_Handle         handle,
    EDMA_errorInfo_t*   errorInfo
)
{
    /* EDMA CC Error reported, Assert ? */
    DebugP_assert(0);
}

/**
 *  @b Description
 *  @n
 *      Call back function for EDMA transfer controller error as per EDMA API.
 *      Declare fatal error if happens, the output errorInfo can be examined if code
 *      gets trapped here.
 *
 *  @param[in]  handle
 *      EDMA driver instance Handle
 *  @param[in]  errorInfo
 *      EDMA Channle id used to copy data buffer
 *
 *  @retval
 *      None
 */
static void SRR_MSS_edmaTransferControllerErrorCallbackFxn
(
    EDMA_Handle                         handle,
    EDMA_transferControllerErrorInfo_t* errorInfo
)
{
    /* EDMA TC Error reported, Assert ? */
    DebugP_assert(0);
}
#endif