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.

AWR1642: AWR1642: Problems changing CAN message IDs

Part Number: AWR1642
Other Parts Discussed in Thread: SYSBIOS

Hello;

I am trying to change the message ID for CAN messages AFTER they have been initially configured.  I am referring to the msgIdentifier field in the CAN_DCANMsgObjCfgParams structure for an existing message box.

I am able to initialize CAN and send and receive messages.  When I wish to change the msgIdentifier during runtime, this appears to work the first time and I can send and receive CAN messages using the new message ID. The second time I try to change the message ID for a message box, it fails.

What is the recommended method for modifying the msgIdentifier field for a message box during runtime?  This is required, for example, for J1939 CAN specification where information is encoded into the message ID which will change over time.  Need to modify the msgIdentifier for a message box many times during the power-on cycle.

There does not appear to be a CAN_modifyMsgObject() or equivalent.  There is a driver function DCANConfigMsgObj() which is used by CAN_createMsgObject() but this is only able to change the message ID once as mentioned above.  Changing the message ID a second time does not work.

Thanks in advance,

Joe Shidle

  • Additional details regarding the failure cases:

    I have tried using CAN_deinit(), reconfiguring the CAN subsystem completely, and CAN_init(). This results in a crash, indicating exceptions in the sysbios subsystem.

    I have tried using CAN_deleteMsgObject() on the message box I wish to change, then recreating it with CAN_createMsgObject(). This works the first time, and I am able to send messages with the new message ID. But a second time, results in a crash indicating a failure to free heap memory in the sysbios subsystem.

    Finally, I have tried calling DCANConfigMsgObj() directly from my app and this works the first time, and I am able to send messages with the new message ID. But when I use it the second or subsequent time, it continues to use the old message ID. For example, if I start with message ID 0x100 then change it 0x101 then everything works and message box transmits go out with 0x101 message ID. If I call the same routine to change it to 0x102, or 0x103, or 0x104, the messages still go out with message ID 0x101.

    I can provide more information if needed.

    The gist of my question though, is still: "How does one change the msgIdentifier field for a message box during run time?"

    Thanks in advance,
    Joe Shidle
  • Hi Joe,

    Thank you for your question. Let me talk to my team and I will have someone get a response to you in the next few days.


    Cheers,
    Akash
  • Hello Joe Shidle,

    We are able to reproduce the issue you have pointed out about the CAN message ID configuration at runtime .

    However, the same issue is not seen on the CANFD interface with CANFD working in CLASSIC CAN mode.

    We are working on providing you a solution for the issue in the CAN driver.
    Thanks for your patience.

    -Raghu
  • Hello Joe Shidle,

    We were able to have configure the CAN message Id at runtime and Tx the message with the modified message Id.

    Below are the code modification done to the dcanTransmit function in the $mmwave_sdk_01_00_00_05\packages\ti\drivers\can\test\common\main.c:

    while (1)
    {

    int32_t j = 1;
    int32_t value;
    /*modify the Tx message identifier */
    appDcanTxCfgParams.msgIdentifier = 0xC1 + j;

    j++;
    if((0xC1+j) > 0xCF)
    {
    j =0;
    }

    /*Create Tx message object here and delete any Tx message object create outside the while() loop*/
    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;
    }

    /* 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++;

    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;
    }

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

    }

    With this change you can create the new TX message object and delete the message object after they are being transmitted. To delete any message object we will need to put the CAN interface in "local power down mode" and then bring it back to normal mode.

    Also below is the snapshot of the messages received on the PCAN from the AWR device with the message ID changed at runtime.

      

    Let me know if this resolves your issue.

    Thanks,

    Raghu

    ---------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.

    ----------------------------------------------------------------------------------------------------------

  • Raghu;

    Thank you for the investigation and response. I will implement this as you suggest and let you know.

    However, I do have a quick question: when the CAN interface is in "local power down mode" with CAN_Option_DCAN_POWER_DOWN set to 1, will the CAN interface still be able to receive CAN messages?

    I am worried about bus reliability during the period of time when the message ID is being changed.

    Again, the SAE J1939 CAN protocol specification relies on modifying the CAN message ID on a semi-regular basis, as a quantity of data is encoded into the 29-bit extended CAN message ID. I am worried that shutting down the CAN interface will disrupt reliability in a field product.

    Best regards,
    Joe Shidle
  • Raghu;

    I have added the relevant code to our application and we are still seeing issues.

    We create a number of message box objects at the start, all with the default message IDs. Then we change the message IDs of the TX message boxes at various points during run time. So there are N message boxes, and T number of TX message boxes and R number of RX message boxes, where T + R = N.

    The way I have implemented your suggestion is as such:

    1) Delete 1 or more message box objects
    2) Create 1 or more new message box objects with the new message IDs
    3) CAN_setOptions() to power down
    4) CAN_setOptions() to wake up
    ... some time later
    5) Transmit with the new message ID

    This works the first time. I am able to change 1 or more of the TX message IDs and then transmit with the new message ID.

    When the time comes to change the message ID a second time, the system hangs.

    Using the debugger, the issue appears to be within the CAN_setOptions() during the power down segment. The system appears to be stuck in the do-while waiting for the system to fully power down.

    Occasionally we will also see this error during run time, which appears during step 2 above (creating new message objects):

    Exception occurred in ThreadType_Hwi.
    Hwi handle: 0x0.
    Hwi stack base: 0x8026100.
    Hwi stack size: 0x1000.
    R0 = 0x08f81e08 R8 = 0x0001ef90
    R1 = 0x00000001 R9 = 0x00000000
    R2 = 0x08015cf4 R10 = 0x00000001
    R3 = 0x08025d50 R11 = 0x00000000
    R4 = 0x08015cc8 R12 = 0xdffc0000
    R5 = 0xfffffdec SP(R13) = 0x080270a0
    R6 = 0x0001f1ca LR(R14) = 0x00006d4c
    R7 = 0x00000002 PC(R15) = 0xdffc0000
    PSR = 0x600c019f
    DFSR = 0x00000000 IFSR = 0x0000000d
    DFAR = 0x00000000 IFAR = 0xdffc0000
    ti.sysbios.family.arm.exc.Exception: line 201: E_prefetchAbort: pc = 0xdffc0000, lr = 0x00006d4c.
    xdc.runtime.Error.raise: terminating execution

    Any additional help you could provide would be greatly appreciated.

    Regards,
    Joe Shidle
  • Hello Joe,
    The sequence that I have in the code is :
    1) Create new message box objects with the new message IDs
    2) Transmit with the new message ID
    3) CAN_setOptions() to power down
    4) CAN_setOptions() to wake up
    ... some time later
    5) Delete the msg box object.

    Running this sequence in the loop.
    Do you see an issue with this sequence?

    -Raghu
  • Hello Joe,

    In case you  want to delete the message objects then we need to follow the process of "local power down" and then "wakeup".

    If you wish to create the multiple message objects during the initialization and then use different message objects to transmit the CAN message without deleting them below is the reference code 

    /*
     *   @file  main.c
     *
     *   @brief
     *      Unit Test code for CAN
     *
     *  \par
     *  NOTE:
     *      (C) Copyright 2016 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>
    
    /* mmWave SK Include Files: */
    #include <ti/common/sys_common.h>
    #include <ti/drivers/soc/soc.h>
    #include <ti/drivers/can/can.h>
    #include <ti/drivers/pinmux/pinmux.h>
    #include <ti/drivers/esm/esm.h>
    #include <ti/utils/testlogger/logger.h>
    #include <ti/drivers/osal/HwiP.h>
    
    /**************************************************************************
     *************************** Global Definitions ***************************
     **************************************************************************/
    
    /** \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              (40000000U)
    
    /** \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                 (0x7U)
    
    
    /** \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 = 4;
    volatile uint32_t       gTxDoneFlag = 0, gRxDoneFlag = 0, gParityErrFlag = 0;
    volatile 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, 4U, &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->msgIdentifier = 0x73;
    
        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->msgIdentifierMask = 0x0;
        dcanRxCfgParams->dirMask           = 0x1;
    
        dcanRxCfgParams->msgValid      = 1;
        dcanRxCfgParams->xIdFlag       = CAN_DCANXidType_11_BIT;
        dcanRxCfgParams->direction     = CAN_Direction_RX;
        //dcanRxCfgParams->msgIdentifier = 0xC1;
        dcanRxCfgParams->msgIdentifier = 0x99;
    
        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[0x0F];
        CAN_MsgObjHandle        rxMsgObjHandle;
        int32_t                 retVal = 0;
        int32_t                 errCode = 0;
    	volatile int32_t j;
        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 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;
        }
    	for( j = 1; j <= 10;j++)
    	{
    		appDcanTxCfgParams.msgIdentifier = 0xC1 + j;
    					
    		
    		 txMsgObjHandle[j] = CAN_createMsgObject (canHandle, j, &appDcanTxCfgParams, &errCode);
    		if (txMsgObjHandle[j] == NULL)
    		{
    			System_printf ("Error: CAN create Tx message object failed [Error code %d]\n", errCode);
    			return -1;
    		}
    		
    		
    	}
    	j = 1;
        while (1)
        {
    		int32_t value;
    
    		if(j>10)
    		{
    			j=1;
    		}
    		/* Send data over Tx message object */
            retVal = CAN_transmitData (txMsgObjHandle[j], &appDcanTxData, &errCode);
            if (retVal < 0)
            {
                System_printf ("Error: CAN transmit data for iteration %d failed [Error code %d]\n", iterationCount, errCode);
                return -1;
                
            }
    		
    
            iterationCount++;
            j++;
            #if 0
    		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;
    		}
    		#endif
            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);
            }
    		//retVal = CAN_deleteMsgObject(txMsgObjHandle, &errCode);
    		//if (retVal < 0)
    		//{
    		//	System_printf ("Error: CAN delete Tx message object failed [Error code %d]\n", errCode);
    		//	return -1;
    		//}
    		Task_sleep(1);
    		
        }
    }
    
    /**
     *  @b Description
     *  @n
     *      System Initialization Task which initializes the various
     *      components in the system.
     *
     *  @retval
     *      Not Applicable.
     */
    static void Test_initTask(UArg arg0, UArg arg1)
    {
        int32_t         retVal = 0;
    
        /* Initialize the test logger framework: */
        MCPI_Initialize ();
    
        /* Initialize the platform */
        retVal = PlatformInit();
        if (retVal < 0)
        {
            MCPI_setFeatureTestResult("Platform initialization failed", MCPI_TestResult_FAIL);
            MCPI_setTestResult ();
            BIOS_exit(0);
        }
    
        while (1)
        {
            System_printf ("*******************************************************\n");
            System_printf ("CAN Unit Test Menu                          \n");
            System_printf ("Please select the type of test to execute:  \n");
            System_printf ("1. DCAN Internal loopback test              \n");
            System_printf ("2. DCAN External loopback test              \n");
            System_printf ("3. DCAN Parity test                         \n");
            System_printf ("4. DCAN Tx/Rx test                          \n");
            System_printf ("*******************************************************\n");
            System_printf ("> Enter your selection: ");
    
            while (testSelection == 0);
    
            /* Validate the selection: */
            if ((testSelection >= DCAN_APP_TEST_INTERNAL_LOOPBACK) && (testSelection <= DCAN_APP_TEST_EXTERNAL_DATA))
                break;
        }
    
        if (testSelection == DCAN_APP_TEST_INTERNAL_LOOPBACK)
        {
            System_printf("Debug: Internal loopback testing\n");
            retVal = dcanLoopbackTest();
            if (retVal == -1)
                MCPI_setFeatureTestResult("Internal loopback testing", MCPI_TestResult_FAIL);
            else
                MCPI_setFeatureTestResult("Internal loopback testing", MCPI_TestResult_PASS);
        }
        else if (testSelection == DCAN_APP_TEST_EXTERNAL_LOOPBACK)
        {
            System_printf("Debug: External loopback testing\n");
            retVal = dcanLoopbackTest();
            if (retVal == -1)
                MCPI_setFeatureTestResult("External loopback testing", MCPI_TestResult_FAIL);
            else
                MCPI_setFeatureTestResult("External loopback testing", MCPI_TestResult_PASS);
        }
        else if (testSelection == DCAN_APP_TEST_PARITY)
        {
            System_printf("Debug: parity testing\n");
            retVal = dcanParityTest();
            if (retVal == -1)
                MCPI_setFeatureTestResult("Parity testing", MCPI_TestResult_FAIL);
            else
                MCPI_setFeatureTestResult("Parity testing", MCPI_TestResult_PASS);
        }
        else if (testSelection == DCAN_APP_TEST_EXTERNAL_DATA)
        {
            System_printf("Debug: External transmit testing\n");
            retVal = dcanTransmitTest();
            if (retVal == -1)
                MCPI_setFeatureTestResult("External transmit testing", MCPI_TestResult_FAIL);
            else
                MCPI_setFeatureTestResult("External transmit testing", MCPI_TestResult_PASS);
        }
        if (retVal < 0)
        {
            System_printf("Debug:CAN testing failed\n");
        }
    
        MCPI_setTestResult ();
    
        /* Exit BIOS */
        BIOS_exit(0);
    
        return;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the entry point into the unit test code
     *
     *  @retval
     *      Not Applicable.
     */
    int32_t main (void)
    {
    	Task_Params     taskParams;
    
        /* Initialize the ESM: Dont clear errors as TI RTOS does it */
        ESM_init(0U);
    
    
        /* Initialize the Task Parameters. */
        Task_Params_init(&taskParams);
        taskParams.stackSize = 6*1024;
        Task_create(Test_initTask, &taskParams, NULL);
    
        /* Start BIOS */
    	BIOS_start();
        return 0;
    }
    
    

    Also attaching a short video clip showing the received data with different message ID by the PCAN application.

    Let me know if you need further information.

    -Raghu

  • Raghu,

    I'm a colleague of Joe Shidle and am attempting to resolve this issue. 

    To cover our issue again, here is what we are attempting to do based on our use case and your suggestions. The key point here is that we need to change our CAN message IDs at random intervals during run-time:

    We can perform the "Run-time Operation", without problems, two times. Upon the third time attempting to delete, create, and perform the power down operation, the first CAN_MsgObjHandle created with CAN_createMsgObject() ends up pointing to a seemingly invalid memory address. This will then throw an exception and halt the system. Please see the debug window below:

    The exception thrown is seen here:

    Exception occurred in ThreadType_Hwi.
    Hwi handle: 0x0.
    Hwi stack base: 0x8026100.
    Hwi stack size: 0x1000.
    R0 = 0x08f81e08 R8 = 0x0001f3b0
    R1 = 0x00000001 R9 = 0x00000000
    R2 = 0x08015cf4 R10 = 0x00000001
    R3 = 0x08025d50 R11 = 0x00000000
    R4 = 0x08015cc8 R12 = 0xdffc0000
    R5 = 0xfffffdec SP(R13) = 0x080270a0
    R6 = 0x0001f5ea LR(R14) = 0x00006edc
    R7 = 0x00000002 PC(R15) = 0xdffc0000
    PSR = 0x600c019f
    DFSR = 0x00000000 IFSR = 0x0000000d
    DFAR = 0x00000000 IFAR = 0xdffc0000
    ti.sysbios.family.arm.exc.Exception: line 201: E_prefetchAbort: pc = 0xdffc0000, lr = 0x00006edc.
    xdc.runtime.Error.raise: terminating execution

    With the exception of transmitting a message for every message box, we are following the suggested sequence of steps listed here:

    Raghunandan Kamath said:

    Hello Joe,
    The sequence that I have in the code is :
    1) Create new message box objects with the new message IDs
    2) Transmit with the new message ID
    3) CAN_setOptions() to power down
    4) CAN_setOptions() to wake up
    ... some time later
    5) Delete the msg box object.

    For testing purposes, I have put in code to transmit on every message box AND added up to 100s of milliseconds worth of delays between some of these steps, but that did not resolve the issue.

     

    Could you please clarify exactly what this means? 

    Raghunandan Kamath said:

    In case you  want to delete the message objects then we need to follow the process of "local power down" and then "wakeup".

    Are we not following the proper power down and wakeup procedure? What else could we be missing?

     

    Thanks,
    Erik

  • Erik,

    Thanks for the detailed explanation of the issue .

    I am actually not able to reproduce the issue that you have mentioned in your reply.

    I have written a code same as you have mentioned in your explanation . Please check the code

    /*
     *   @file  main.c
     *
     *   @brief
     *      Unit Test code for CAN
     *
     *  \par
     *  NOTE:
     *      (C) Copyright 2016 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>
    
    /* mmWave SK Include Files: */
    #include <ti/common/sys_common.h>
    #include <ti/drivers/soc/soc.h>
    #include <ti/drivers/can/can.h>
    #include <ti/drivers/pinmux/pinmux.h>
    #include <ti/drivers/esm/esm.h>
    #include <ti/utils/testlogger/logger.h>
    #include <ti/drivers/osal/HwiP.h>
    
    /**************************************************************************
     *************************** Global Definitions ***************************
     **************************************************************************/
    
    /** \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              (40000000U)
    
    /** \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                 (0x7U)
    
    
    /** \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 = 4;
    volatile uint32_t       gTxDoneFlag = 0, gRxDoneFlag = 0, gParityErrFlag = 0;
    volatile 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, 4U, &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->msgIdentifier = 0x73;
    
        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->msgIdentifierMask = 0x0;
        dcanRxCfgParams->dirMask           = 0x1;
    
        dcanRxCfgParams->msgValid      = 1;
        dcanRxCfgParams->xIdFlag       = CAN_DCANXidType_11_BIT;
        dcanRxCfgParams->direction     = CAN_Direction_RX;
        //dcanRxCfgParams->msgIdentifier = 0xC1;
        dcanRxCfgParams->msgIdentifier = 0x99;
    
        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[24];
        CAN_MsgObjHandle        rxMsgObjHandle;
        int32_t                 retVal = 0;
        int32_t                 errCode = 0;
    	volatile int32_t j;
        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 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;
        }
    	for( j = 1; j <= 22;j++)
    	{
    		appDcanTxCfgParams.msgIdentifier = 0xC1 + j;
    					
    		
    		 txMsgObjHandle[j] = CAN_createMsgObject (canHandle, j, &appDcanTxCfgParams, &errCode);
    		if (txMsgObjHandle[j] == NULL)
    		{
    			System_printf ("Error: CAN create Tx message object failed [Error code %d]\n", errCode);
    			return -1;
    		}
    		
    		
    	}
    	j = 1;
        while (1)
        {
    		int32_t value;
    
    		if(j>22)
    		{
    			j--;
    			while(j!=0){
    				retVal = CAN_deleteMsgObject(txMsgObjHandle[j], &errCode);
    				if (retVal < 0)
    				{
    					System_printf ("Error: CAN delete Tx message object failed [Error code %d]\n", errCode);
    					return -1;
    				}
    				j--;
    			}
    			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;
    			}
    			
    			for( j = 1; j <= 22;j++)
    			{
    				appDcanTxCfgParams.msgIdentifier = 0xd1 + j;
    							
    				
    				 txMsgObjHandle[j] = CAN_createMsgObject (canHandle, j, &appDcanTxCfgParams, &errCode);
    				if (txMsgObjHandle[j] == NULL)
    				{
    					System_printf ("Error: CAN create Tx message object failed [Error code %d]\n", errCode);
    					return -1;
    				}
    				
    				
    			}
    			j = 1;
    			
    		}
    		#if 1
    		/* Send data over Tx message object */
            retVal = CAN_transmitData (txMsgObjHandle[j], &appDcanTxData, &errCode);
            if (retVal < 0)
            {
                System_printf ("Error: CAN transmit data for iteration %d failed [Error code %d]\n", iterationCount, errCode);
                return -1;
                
            }
    		
    		#endif
            iterationCount++;
            j++;
            #if 0
    		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;
    		}
    		#endif
            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);
            }
    		//retVal = CAN_deleteMsgObject(txMsgObjHandle, &errCode);
    		//if (retVal < 0)
    		//{
    		//	System_printf ("Error: CAN delete Tx message object failed [Error code %d]\n", errCode);
    		//	return -1;
    		//}
    		Task_sleep(1);
    		
        }
    }
    
    /**
     *  @b Description
     *  @n
     *      System Initialization Task which initializes the various
     *      components in the system.
     *
     *  @retval
     *      Not Applicable.
     */
    static void Test_initTask(UArg arg0, UArg arg1)
    {
        int32_t         retVal = 0;
    
        /* Initialize the test logger framework: */
        MCPI_Initialize ();
    
        /* Initialize the platform */
        retVal = PlatformInit();
        if (retVal < 0)
        {
            MCPI_setFeatureTestResult("Platform initialization failed", MCPI_TestResult_FAIL);
            MCPI_setTestResult ();
            BIOS_exit(0);
        }
    
        while (1)
        {
            System_printf ("*******************************************************\n");
            System_printf ("CAN Unit Test Menu                          \n");
            System_printf ("Please select the type of test to execute:  \n");
            System_printf ("1. DCAN Internal loopback test              \n");
            System_printf ("2. DCAN External loopback test              \n");
            System_printf ("3. DCAN Parity test                         \n");
            System_printf ("4. DCAN Tx/Rx test                          \n");
            System_printf ("*******************************************************\n");
            System_printf ("> Enter your selection: ");
    
            while (testSelection == 0);
    
            /* Validate the selection: */
            if ((testSelection >= DCAN_APP_TEST_INTERNAL_LOOPBACK) && (testSelection <= DCAN_APP_TEST_EXTERNAL_DATA))
                break;
        }
    
        if (testSelection == DCAN_APP_TEST_INTERNAL_LOOPBACK)
        {
            System_printf("Debug: Internal loopback testing\n");
            retVal = dcanLoopbackTest();
            if (retVal == -1)
                MCPI_setFeatureTestResult("Internal loopback testing", MCPI_TestResult_FAIL);
            else
                MCPI_setFeatureTestResult("Internal loopback testing", MCPI_TestResult_PASS);
        }
        else if (testSelection == DCAN_APP_TEST_EXTERNAL_LOOPBACK)
        {
            System_printf("Debug: External loopback testing\n");
            retVal = dcanLoopbackTest();
            if (retVal == -1)
                MCPI_setFeatureTestResult("External loopback testing", MCPI_TestResult_FAIL);
            else
                MCPI_setFeatureTestResult("External loopback testing", MCPI_TestResult_PASS);
        }
        else if (testSelection == DCAN_APP_TEST_PARITY)
        {
            System_printf("Debug: parity testing\n");
            retVal = dcanParityTest();
            if (retVal == -1)
                MCPI_setFeatureTestResult("Parity testing", MCPI_TestResult_FAIL);
            else
                MCPI_setFeatureTestResult("Parity testing", MCPI_TestResult_PASS);
        }
        else if (testSelection == DCAN_APP_TEST_EXTERNAL_DATA)
        {
            System_printf("Debug: External transmit testing\n");
            retVal = dcanTransmitTest();
            if (retVal == -1)
                MCPI_setFeatureTestResult("External transmit testing", MCPI_TestResult_FAIL);
            else
                MCPI_setFeatureTestResult("External transmit testing", MCPI_TestResult_PASS);
        }
        if (retVal < 0)
        {
            System_printf("Debug:CAN testing failed\n");
        }
    
        MCPI_setTestResult ();
    
        /* Exit BIOS */
        BIOS_exit(0);
    
        return;
    }
    
    /**
     *  @b Description
     *  @n
     *      This is the entry point into the unit test code
     *
     *  @retval
     *      Not Applicable.
     */
    int32_t main (void)
    {
    	Task_Params     taskParams;
    
        /* Initialize the ESM: Dont clear errors as TI RTOS does it */
        ESM_init(0U);
    
    
        /* Initialize the Task Parameters. */
        Task_Params_init(&taskParams);
        taskParams.stackSize = 6*1024;
        Task_create(Test_initTask, &taskParams, NULL);
    
        /* Start BIOS */
    	BIOS_start();
        return 0;
    }
    
    

    I have modified the "dcanTransmitTest()" as per  your  writeup.I have written the code for about 22 messages as a sample.

    Please look at my application code and let me know if it suits your requirement or alternately you can send upload the changes you have done in your DCAN transmit code so that I can reproduce the issue here on my setup.

    With reference to your requirement, how many different message identifiers do you have to transmit during the runtime?

    Thanks,

    Raghu

     

  • Raghu,

    Thanks for your help. First, there was an issue on our side due to the way we were storing received CAN messages. This was causing memory corruption, hence the garbage returned when creating CAN message objects.

    Second, as the code in your 2604.main.c shows, the order of delete, set, then create was critical.

    I can't say exactly how many message IDs are required during runtime, but the critical requirement was that we can change them at runtime an unrestricted number of times.

    Thanks,
    Erik
  • Hello Erik,
    Thanks for your update.

    If the issue is resolved , please mark the response that resolved the issue and close the post.

    Thanks,
    Raghu