/* ======================================================================
 *   Copyright (C) 2014 Texas Instruments Incorporated
 *
 *   All rights reserved. Property of Texas Instruments Incorporated.
 *   Restricted rights to use, duplicate or disclose this code are
 *   granted through contract.
 *
 *   The program may not be used without the written permission
 *   of Texas Instruments Incorporated or against the terms and conditions
 *   stipulated in the agreement under which this program has been
 *   supplied.
 * ==================================================================== */

/**
 *******************************************************************************
 * \file utils_dcan.c
 *
 * \brief  This file implements the DCAN TX/RX functionality
 *
 *
 *
 * \version 0.0 (Dec 2014) : First version
 *
 *******************************************************************************
*/

/*******************************************************************************
 *  INCLUDE FILES
 *******************************************************************************
 */
/* ========================================================================== */
/*                             Include Files                                  */
/* ========================================================================== */
#include <stdint.h>
#include <string.h>
#include <xdc/std.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Event.h>
#include <ti/sysbios/gates/GateMutexPri.h>
#include <ti/sysbios/family/shared/vayu/IntXbar.h>

#include "common/stw_types.h"
#include "common/stw_utils.h"
#include "hw_types.h"
#include "irq_xbar_interrupt_ids.h"
#include "soc.h"
#include "soc_defines.h"
#include "platform.h"

#include "include/link_api/system.h"
#include "include/link_api/system_common.h"

/* Application header files */
#include "src/utils_common/include/utils.h"
#include "src/utils_common/include/utils_que.h"
#include "src/utils_common/include/utils_tsk.h"
#include "utils_dcan.h"





/* ========================================================================== */
/*                                Macros                                      */
/* ========================================================================== */

/** \brief Used for enabling DCAN1 and DCAN2 */

#define ENABLE_DCAN1_FLAG             (1U)

#define ENABLE_DCAN2_FLAG             (0U)


/** \brief DCAN instance used */
#define UTILS_DCAN_INST                   (SOC_DCAN1_BASE)
//#define UTILS_DCAN_INST                   (SOC_DCAN2_BASE)



/** \brief DCAN bit time calculation maximum error value. */
#define UTILS_DCAN_CALC_MAX_ERROR         (50U)

/** \brief Macro used to extract bit rate prescaler value. */
#define UTILS_DCAN_EXTRACT_BRPE_VAL       (0x3C0U)

/** \brief Shift value used for bit rate prescaler. */
#define UTILS_DCAN_BRPE_SHIFT             (6U)


/** \brief DCAN TX message object used */
#define UTILS_DCAN_TX_MSG_OBJ                 (0x1U)
/** \brief DCAN RX message object used */
#define UTILS_DCAN_RX_MSG_OBJ                 (0x2U)
/** \brief DCAN TX message object used */
#define UTILS_DCAN_TX_ACK_MSG_OBJ             (0x3U)
/** \brief DCAN RX message object used */
#define UTILS_DCAN_RX_ACK_MSG_OBJ             (0x4U)

#define UTILS_DCAN_CTRL_MSG_ID                (0x500)
#define UTILS_DCAN_CTRL_ACK_MSG_ID            (0xC2)

#define UTILS_DCAN_RX_MSG_OBJ1                 (0x5U)
#define UTILS_DCAN_CTRL_MSG_ID1                (0x501)

#define UTILS_DCAN_RX_MSG_OBJ2                 (0x6U)
#define UTILS_DCAN_CTRL_MSG_ID2                (0x502)

#define UTILS_DCAN_RX_MSG_OBJ3                 (0x7U)
#define UTILS_DCAN_CTRL_MSG_ID3                (0x503)

#define UTILS_DCAN_RX_MSG_OBJ4                 (0x8U)
#define UTILS_DCAN_CTRL_MSG_ID4                (0x504)

#define UTILS_DCAN_RX_MSG_OBJ5                 (0x9U)
#define UTILS_DCAN_CTRL_MSG_ID5                (0x505)

#define UTILS_DCAN_RX_MSG_OBJ6                 (0xAU)
#define UTILS_DCAN_CTRL_MSG_ID6                (0x506)

#define UTILS_DCAN_RX_MSG_OBJ7                 (0xBU)
#define UTILS_DCAN_CTRL_MSG_ID7                (0x507)

#define UTILS_DCAN_RX_MSG_OBJ8                 (0xCU)
#define UTILS_DCAN_CTRL_MSG_ID8                (0x508)

#define UTILS_DCAN_RX_MSG_OBJ9                 (0xDU)
#define UTILS_DCAN_CTRL_MSG_ID9                (0x509)

#define UTILS_DCAN_RX_MSG_OBJ10                (0xEU)
#define UTILS_DCAN_CTRL_MSG_ID10               (0x50A)

#define UTILS_DCAN_RX_MSG_OBJ11                (0xFU)
#define UTILS_DCAN_CTRL_MSG_ID11               (0x50B)

#define UTILS_DCAN_RX_MSG_OBJ12                (0x10U)
#define UTILS_DCAN_CTRL_MSG_ID12               (0x50C)

#define UTILS_DCAN_RX_MSG_OBJ13                (0x11U)
#define UTILS_DCAN_CTRL_MSG_ID13               (0x50D)

#define UTILS_DCAN_RX_MSG_OBJ14                (0x12U)
#define UTILS_DCAN_CTRL_MSG_ID14               (0x50E)

#define UTILS_DCAN_RX_MSG_OBJ15                (0x13U)
#define UTILS_DCAN_CTRL_MSG_ID15               (0x50F)

#define UTILS_DCAN_RX_MSG_OBJ16                (0x14U)
#define UTILS_DCAN_CTRL_MSG_ID16               (0x510)

#define UTILS_DCAN_RX_MSG_OBJ17                (0x15U)
#define UTILS_DCAN_CTRL_MSG_ID17               (0x511)

#define UTILS_DCAN_RX_MSG_OBJ18                (0x16U)
#define UTILS_DCAN_CTRL_MSG_ID18               (0x512)

#define UTILS_DCAN_RX_MSG_OBJ19                (0x17U)
#define UTILS_DCAN_CTRL_MSG_ID19               (0x513)

#define UTILS_DCAN_RX_MSG_OBJ20                (0x18U)
#define UTILS_DCAN_CTRL_MSG_ID20               (0x514)

#define UTILS_DCAN_RX_MSG_OBJ21                (0x19U)
#define UTILS_DCAN_CTRL_MSG_ID21               (0x515)

#define UTILS_DCAN_RX_MSG_OBJ22                (0x1AU)
#define UTILS_DCAN_CTRL_MSG_ID22               (0x516)

#define UTILS_DCAN_RX_MSG_OBJ23                (0x1BU)
#define UTILS_DCAN_CTRL_MSG_ID23               (0x517)

#define UTILS_DCAN_RX_MSG_OBJ24                (0x1CU)
#define UTILS_DCAN_CTRL_MSG_ID24               (0x518)

#define UTILS_DCAN_RX_MSG_OBJ25                (0x1DU)
#define UTILS_DCAN_CTRL_MSG_ID25               (0x519)

#define UTILS_DCAN_RX_MSG_OBJ26                (0x1EU)
#define UTILS_DCAN_CTRL_MSG_ID26               (0x51A)

#define UTILS_DCAN_RX_MSG_OBJ27                (0x1FU)
#define UTILS_DCAN_CTRL_MSG_ID27               (0x51B)

#define UTILS_DCAN_RX_MSG_OBJ28                (0x20U)
#define UTILS_DCAN_CTRL_MSG_ID28               (0x51C)

#define UTILS_DCAN_RX_MSG_OBJ29                (0x21U)
#define UTILS_DCAN_CTRL_MSG_ID29               (0x51D)

#define UTILS_DCAN_RX_MSG_OBJ30                (0x22U)
#define UTILS_DCAN_CTRL_MSG_ID30               (0x51E)

#define UTILS_DCAN_RX_MSG_OBJ31                (0x23U)
#define UTILS_DCAN_CTRL_MSG_ID31               (0x51F)

#define UTILS_DCAN_RX_MSG_OBJ32                (0x24U)
#define UTILS_DCAN_CTRL_MSG_ID32               (0x520)

#define UTILS_DCAN_RX_MSG_OBJ33                (0x25U)
#define UTILS_DCAN_CTRL_MSG_ID33               (0x521)

#define UTILS_DCAN_RX_MSG_OBJ34                (0x26U)
#define UTILS_DCAN_CTRL_MSG_ID34               (0x522)

#define UTILS_DCAN_RX_MSG_OBJ35                (0x27U)
#define UTILS_DCAN_CTRL_MSG_ID35               (0x523)

#define UTILS_DCAN_RX_MSG_OBJ36                (0x28U)
#define UTILS_DCAN_CTRL_MSG_ID36               (0x524)

#define UTILS_DCAN_RX_MSG_OBJ37                (0x29U)
#define UTILS_DCAN_CTRL_MSG_ID37               (0x525)

#define UTILS_DCAN_RX_MSG_OBJ38                (0x2AU)
#define UTILS_DCAN_CTRL_MSG_ID38               (0x526)

#define UTILS_DCAN_RX_MSG_OBJ39                (0x2BU)
#define UTILS_DCAN_CTRL_MSG_ID39               (0x527)

#define UTILS_DCAN_RX_MSG_OBJ40                (0x2CU)
#define UTILS_DCAN_CTRL_MSG_ID40               (0x528)

#define UTILS_DCAN_RX_MSG_OBJ41                (0x2DU)
#define UTILS_DCAN_CTRL_MSG_ID41               (0x529)

#define UTILS_DCAN_RX_MSG_OBJ42                (0x2EU)
#define UTILS_DCAN_CTRL_MSG_ID42               (0x52A)

#define UTILS_DCAN_RX_MSG_OBJ43                (0x2FU)
#define UTILS_DCAN_CTRL_MSG_ID43               (0x52B)

#define UTILS_DCAN_RX_MSG_OBJ44                (0x30U)
#define UTILS_DCAN_CTRL_MSG_ID44               (0x52C)

#define UTILS_DCAN_RX_MSG_OBJ45                (0x31U)
#define UTILS_DCAN_CTRL_MSG_ID45               (0x52D)

#define UTILS_DCAN_RX_MSG_OBJ46                (0x32U)
#define UTILS_DCAN_CTRL_MSG_ID46               (0x52E)

#define UTILS_DCAN_RX_MSG_OBJ47                (0x33U)
#define UTILS_DCAN_CTRL_MSG_ID47               (0x52F)

#define UTILS_DCAN_RX_MSG_OBJ48                (0x34U)
#define UTILS_DCAN_CTRL_MSG_ID48               (0x530)

#define UTILS_DCAN_RX_MSG_OBJ49                (0x35U)
#define UTILS_DCAN_CTRL_MSG_ID49               (0x531)

#define UTILS_DCAN_RX_MSG_OBJ50                (0x36U)
#define UTILS_DCAN_CTRL_MSG_ID50               (0x532)

#define UTILS_DCAN_RX_MSG_OBJ51                (0x37U)
#define UTILS_DCAN_CTRL_MSG_ID51               (0x533)

#define UTILS_DCAN_RX_MSG_OBJ52                (0x38U)
#define UTILS_DCAN_CTRL_MSG_ID52               (0x534)

#define UTILS_DCAN_RX_MSG_OBJ53                (0x39U)
#define UTILS_DCAN_CTRL_MSG_ID53               (0x535)

#define UTILS_DCAN_RX_MSG_OBJ54                (0x3AU)
#define UTILS_DCAN_CTRL_MSG_ID54               (0x536)

#define UTILS_DCAN_RX_MSG_OBJ55                (0x3BU)
#define UTILS_DCAN_CTRL_MSG_ID55               (0x537)

#define UTILS_DCAN_RX_MSG_OBJ56                (0x3CU)
#define UTILS_DCAN_CTRL_MSG_ID56               (0x538)

#define UTILS_DCAN_RX_MSG_OBJ57                (0x3DU)
#define UTILS_DCAN_CTRL_MSG_ID57               (0x539)

#define UTILS_DCAN_RX_MSG_OBJ58                (0x3EU)
#define UTILS_DCAN_CTRL_MSG_ID58               (0x53A)

#define UTILS_DCAN_RX_MSG_OBJ59                (0x3FU)
#define UTILS_DCAN_CTRL_MSG_ID59               (0x53B)

#define UTILS_DCAN_RX_MSG_OBJ60                (0x40U)
#define UTILS_DCAN_CTRL_MSG_ID60               (0x53C)

#define UTILS_DCAN_RX_MSG_OBJ61                (0x41U)
#define UTILS_DCAN_CTRL_MSG_ID61               (0x53D)

#define UTILS_DCAN_RX_MSG_OBJ62                (0x42U)
#define UTILS_DCAN_CTRL_MSG_ID62               (0x53E)

#define UTILS_DCAN_RX_MSG_OBJ63                (0x43U)
#define UTILS_DCAN_CTRL_MSG_ID63               (0x53F)


/** \brief DCAN TX interface register used */
#define UTILS_DCAN_TX_IF_REG              (DCAN_IF_REG_NUM_1)
/** \brief DCAN RX interface register used */
#define UTILS_DCAN_RX_IF_REG              (DCAN_IF_REG_NUM_2)

/** \brief Offset of DRM SUSPEND_CTRL1 register */
#define DRM_SUSPEND_CTRL1               (0x204)
/** \brief DRM_SUSPEND_CTRL1 is mapped to DCAN1 Suspend Output line */
#define DRM_SUSPEND_CTRL_DCAN1          (SOC_I_DRM_BASE + DRM_SUSPEND_CTRL1)

/** \brief DRM SUSPEND Source as M4 */
#define DRM_SUSPEND_SRC_IPU1_C0         (0x3)


#define UTILS_DCAN_MAX_QUEUE_PER_MBX    (0x2U)


#define UTILS_DCAN_TSK_EXIT_EVENT       (Event_Id_31)
#define UTILS_DCAN_TX_PRD_EVENT         (Event_Id_00)




/* ========================================================================== */
/*                         Structures and Enums                               */
/* ========================================================================== */

/**
 *  \brief    Enumerates the values used to represent the DCAN bit time
 *            calculation error values.
 */
typedef enum dcanBitTimeCalcErrType
{
    DCAN_BIT_RATE_ERR_MAX = 1,
    /**< Bitrate error maximum value */
    DCAN_BIT_RATE_ERR_WARN = 2,
    /**< Bitrate error warning value */
    DCAN_BIT_RATE_ERR_NONE = 3
                             /**< No bit rate error */
} dcanBitTimeCalcErrType_t;

typedef enum dcanQueMsgState_e
{
    DCAN_MSG_STATE_IN_FREEQ,
    DCAN_MSG_STATE_IN_RX_QUE,
    DCAN_MSG_STATE_ISR,
    DCAN_MSG_STATE_MSG_RX,
    DCAN_MSG_STATE_MSG_TX,
    DCAN_MSG_STATE_MSG_RX_ACK
} dcanQueMsgState_e;

typedef enum dcanRxTaskState_e
{
    DCAN_RX_TSK_STATE_START,
    DCAN_RX_TSK_STATE_WAITEVENT,
    DCAN_RX_TSK_STATE_RXMSGCALLBACK,
    DCAN_RX_TSK_STATE_RXACK,
    DCAN_RX_TSK_STATE_STOP
} dcanRxTaskState_e;

typedef enum dcanTxTaskState_e
{
    DCAN_TX_TSK_STATE_START,
    DCAN_TX_TSK_STATE_WAITEVENT,
    DCAN_TX_TSK_STATE_SENDMSG,
    DCAN_TX_TSK_STATE_PROCESSACK,
    DCAN_TX_TSK_STATE_STOP
} dcanTxTaskState_e;

/** \brief Structure holding Bit Time parameters for DCAN application. */
typedef struct dcanBitTimeParamsLocal
{
    UInt32 samplePnt;
    UInt32 timeQuanta;
    UInt32 propSeg;
    UInt32 phaseSeg1;
    UInt32 phaseSeg2;
    UInt32 syncJumpWidth;
    UInt32 bitRatePrescaler;
    UInt32 tseg1Min;
    UInt32 tseg1Max;
    UInt32 tseg2Min;
    UInt32 tseg2Max;
    UInt32 syncJumpWidthMax;
    UInt32 bitRatePrescalerMin;
    UInt32 bitRatePrescalerMax;
    UInt32 bitRatePrescalerInc;
    UInt32 bitRate;
} dcanBitTimeParamsLocal_t;

//this array used for what
const UInt32 dcanRxMbxId[] = {UTILS_DCAN_RX_MSG_OBJ,UTILS_DCAN_RX_ACK_MSG_OBJ,UTILS_DCAN_RX_MSG_OBJ1
                   ,UTILS_DCAN_RX_MSG_OBJ2,UTILS_DCAN_RX_MSG_OBJ3,UTILS_DCAN_RX_MSG_OBJ4
                   ,UTILS_DCAN_RX_MSG_OBJ5,UTILS_DCAN_RX_MSG_OBJ6,UTILS_DCAN_RX_MSG_OBJ7
                   ,UTILS_DCAN_RX_MSG_OBJ8,UTILS_DCAN_RX_MSG_OBJ9,UTILS_DCAN_RX_MSG_OBJ10
                   ,UTILS_DCAN_RX_MSG_OBJ11,UTILS_DCAN_RX_MSG_OBJ12,UTILS_DCAN_RX_MSG_OBJ13
                   ,UTILS_DCAN_RX_MSG_OBJ14,UTILS_DCAN_RX_MSG_OBJ15,UTILS_DCAN_RX_MSG_OBJ16
                   ,UTILS_DCAN_RX_MSG_OBJ17,UTILS_DCAN_RX_MSG_OBJ18,UTILS_DCAN_RX_MSG_OBJ19
                   ,UTILS_DCAN_RX_MSG_OBJ20,UTILS_DCAN_RX_MSG_OBJ21,UTILS_DCAN_RX_MSG_OBJ22
                   ,UTILS_DCAN_RX_MSG_OBJ23,UTILS_DCAN_RX_MSG_OBJ24,UTILS_DCAN_RX_MSG_OBJ25
                   ,UTILS_DCAN_RX_MSG_OBJ26,UTILS_DCAN_RX_MSG_OBJ27,UTILS_DCAN_RX_MSG_OBJ28
                   ,UTILS_DCAN_RX_MSG_OBJ29,UTILS_DCAN_RX_MSG_OBJ30,UTILS_DCAN_RX_MSG_OBJ31
                   ,UTILS_DCAN_RX_MSG_OBJ32,UTILS_DCAN_RX_MSG_OBJ33,UTILS_DCAN_RX_MSG_OBJ34
                   ,UTILS_DCAN_RX_MSG_OBJ35,UTILS_DCAN_RX_MSG_OBJ36,UTILS_DCAN_RX_MSG_OBJ37
                   ,UTILS_DCAN_RX_MSG_OBJ38,UTILS_DCAN_RX_MSG_OBJ39,UTILS_DCAN_RX_MSG_OBJ40
                   ,UTILS_DCAN_RX_MSG_OBJ41,UTILS_DCAN_RX_MSG_OBJ42,UTILS_DCAN_RX_MSG_OBJ43
                   ,UTILS_DCAN_RX_MSG_OBJ44,UTILS_DCAN_RX_MSG_OBJ45,UTILS_DCAN_RX_MSG_OBJ46
                   ,UTILS_DCAN_RX_MSG_OBJ47,UTILS_DCAN_RX_MSG_OBJ48,UTILS_DCAN_RX_MSG_OBJ49
                   ,UTILS_DCAN_RX_MSG_OBJ50,UTILS_DCAN_RX_MSG_OBJ51,UTILS_DCAN_RX_MSG_OBJ52
                   ,UTILS_DCAN_RX_MSG_OBJ53,UTILS_DCAN_RX_MSG_OBJ54,UTILS_DCAN_RX_MSG_OBJ55
                   ,UTILS_DCAN_RX_MSG_OBJ56,UTILS_DCAN_RX_MSG_OBJ57,UTILS_DCAN_RX_MSG_OBJ58
                   ,UTILS_DCAN_RX_MSG_OBJ59,UTILS_DCAN_RX_MSG_OBJ60,UTILS_DCAN_RX_MSG_OBJ61
                   ,UTILS_DCAN_RX_MSG_OBJ61,UTILS_DCAN_RX_MSG_OBJ62,UTILS_DCAN_RX_MSG_OBJ63}; 
const UInt32 dcanTxMbxId[] = {UTILS_DCAN_TX_MSG_OBJ,UTILS_DCAN_TX_ACK_MSG_OBJ};

#define UTILS_DCAN_NUM_RX_MAILBOX       (UTILS_ARRAYSIZE(dcanRxMbxId))
#define UTILS_DCAN_NUM_TX_MAILBOX       (UTILS_ARRAYSIZE(dcanTxMbxId))

typedef struct dcanRxMsgObj_tag
{
    BspOsal_TaskHandle dcanRxTsk;
    /**< DCAN RX thread */

    Event_Handle dcanRxEvent;
    Event_Struct dcanRxEventMem;
    UInt32 mbxMask;
    dcanRxTaskState_e state;

    struct dcanQueMsgs_s {
        dcanMsg_t msg;
        dcanQueMsgState_e  state;
    } dcanQueMsgs[(UTILS_DCAN_NUM_RX_MAILBOX * UTILS_DCAN_MAX_QUEUE_PER_MBX)];
    
    struct freeQ_t {
        Utils_QueHandle handle;
        struct dcanQueMsgs_s  *queMem[(UTILS_DCAN_NUM_RX_MAILBOX * UTILS_DCAN_MAX_QUEUE_PER_MBX)];
    } freeQ;
    
    struct rxMsgQ_t {
        Utils_QueHandle handle;
        struct dcanQueMsgs_s  *queMem[UTILS_DCAN_MAX_QUEUE_PER_MBX * 4];
    } rxMsgQ[UTILS_DCAN_NUM_RX_MAILBOX];
} dcanRxMsgObj_t;

typedef struct dcanTxMsgAckObj_tag
{
  BspOsal_SemHandle semTxComplete;
  /**< Tx complete semaphore handle */

}dcanTxMsgAck_t;


typedef struct dcanTxMsgPeriodicObj_t
{
    BspOsal_ClockHandle clkHandle;
    Bool clkStarted;
} dcanTxMsgPeriodicObj_t;



typedef struct dcanTxMsgObj_tag
{
    BspOsal_TaskHandle dcanTxTsk;
    /**< DCAN RX thread */
    dcanTxTaskState_e state;
    Event_Handle dcanRxAckEvent;
    Utils_QueHandle *dcanRxAckQue;
    Utils_QueHandle *dcanRxAckFreeQue;
    Event_Handle dcanTxEvent;
    Event_Struct dcanTxEventMem;
    dcanTxMsgPeriodicObj_t prd;
    dcanTxMsgAck_t dcanTxMsgAckObj[UTILS_DCAN_NUM_TX_MAILBOX];
} dcanTxMsgObj_t;


typedef struct dcanMbx2MsgIdMap_tag
{
    UInt32 mbxId;
    UInt32 msgId;
} dcanMbx2MsgIdMap_t;

typedef struct dcanIsrContext_tag
{
    dcanRxMsgObj_t *rxMsgObj;
    dcanTxMsgObj_t *txMsgObj;
    BspOsal_IntrHandle  hwi;
    GateMutexPri_Handle mutex;
    GateMutexPri_Struct mutexMem;
} dcanIsrContext_t;


#define UTILS_DCAN_TSK_STACK_SIZE (2 * 1024)

#pragma DATA_ALIGN(gUtilsDcanRx_tskStack, 32)
#pragma DATA_SECTION(gUtilsDcanRx_tskStack, ".bss:taskStackSection")
static UInt8 gUtilsDcanRx_tskStack[UTILS_DCAN_TSK_STACK_SIZE];

#pragma DATA_ALIGN(gUtilsDcanTx_tskStack, 32)
#pragma DATA_SECTION(gUtilsDcanTx_tskStack, ".bss:taskStackSection")
static UInt8 gUtilsDcanTx_tskStack[UTILS_DCAN_TSK_STACK_SIZE];


static dcanRxMsgObj_t dcanRxMsgObj;
static dcanTxMsgObj_t dcanTxMsgObj;
static dcanIsrContext_t dcanIsrContext;
static dcanConfig_t dcanConfig;

static dcanMbx2MsgIdMap_t dcanMbx2MsgIdMap[UTILS_DCAN_NUM_TX_MAILBOX + UTILS_DCAN_NUM_RX_MAILBOX];

static Bool dcanInitDone = FALSE;

static IArg Utils_dcanTxMutexEnter();
static Void Utils_dcanTxMutexLeave(IArg key);
static void Utils_dcanWaitForIfReg(UInt32 baseAddr, UInt32 ifRegNum);
static void Utils_dcanInitTxMsgParams(dcanTxParams_t *pDcanTxPrms,
                                      UInt8 *msgData,
                                      UInt8 length);
static void Utils_dcanInitRxMsgObjParams(dcanMsgObjCfgParams_t *pDcanRxCfgPrms,
                                         UInt32 msgId,UInt32 msgType);
static void Utils_dcanInitTxMsgObjParams(dcanMsgObjCfgParams_t *pDcanTxCfgPrms,
                                         UInt32 msgId,UInt32 msgType);
static void Utils_dcanInitControllerParams(dcanCfgParams_t       *pDcanCfgPrms);
static void Utils_dcanUnRegisterIntr(void);
static void Utils_dcanConfigIntr(void);
static void Utils_dcanInt1Isr();

static UInt32 Utils_dcanBitTimeCalculator(
    dcanBitTimeParamsLocal_t *pBitTimeParam,
    UInt32                  clkFreq);

static int32_t Utils_dcanUpdateSamplePnt(dcanBitTimeParamsLocal_t *pBitTimeParam,
                                      int32_t                   samplePnt,
                                      int32_t                   tseg,
                                      int32_t                  *tseg1,
                                      int32_t                  *tseg2);


static void Utils_dcanWaitForIfReg(UInt32 baseAddr, UInt32 ifRegNum);
static UInt32 Utils_dcanCalculateBitTimeParams(UInt32             clkFreq,
                                                 UInt32             bitRate,
                                                 dcanBitTimeParams_t *pBitTimePrms);
static Void Utils_dcanTxSendMsg();
static UInt Utils_dcanGetTxMbxIndex(UInt32 mailBoxId);
static void Utils_dcanConfigRxMsgObj(UInt32 rxMailboxId);
static Void Utils_dcanSetMailboxMsgId(UInt32 mailboxId,UInt32 msgId);


/* ========================================================================== */
/*                          Function Declarations                             */
/* ========================================================================== */

/**
  *****************************************************************************
  * \brief UtilsDcan wrapper around Utils_quePut
  *
  *  Function performs additional setting of msg state before putting in que
  *
  *****************************************************************************
*/
static Void  Utils_dcanQuePut(Utils_QueHandle * handle, struct dcanQueMsgs_s *msg,
                              dcanQueMsgState_e state)
{
    Int32 status;

    msg->state = state;
    status = Utils_quePut(handle,msg,BIOS_NO_WAIT);
    UTILS_assert(status == 0);
}

/**
  *****************************************************************************
  * \brief UtilsDcan wrapper around Utils_queGet
  *
  *  Function performs additional checks on msg state
  *
  *****************************************************************************
*/
static Void  Utils_dcanQueGet(Utils_QueHandle * handle,
                              struct dcanQueMsgs_s **msgPtr,
                              dcanMsg_t **rxMsgPtr,
                              dcanQueMsgState_e expectedState,
                              dcanQueMsgState_e newState)
{
    Int32 status;


    status = Utils_queGet(handle,(Ptr *)msgPtr,1, BIOS_NO_WAIT);
    UTILS_assert(status == 0);
    UTILS_assert((*msgPtr)->state == expectedState);
    (*msgPtr)->state = newState;
    *rxMsgPtr = &((*msgPtr)->msg);
}


/**
  *****************************************************************************
  * \brief PRD callout function
  *
  *****************************************************************************
*/
static Void Utils_dcanPrdCalloutFcn(UArg arg)
{
    dcanTxMsgObj_t *pObj = (dcanTxMsgObj_t *) arg;

    Event_post (pObj->dcanTxEvent,UTILS_DCAN_TX_PRD_EVENT);

}

/**
  *****************************************************************************
  * \brief Create prd object
  *
  *****************************************************************************
*/
static Void Utils_dcanCreatePrdObj(dcanTxMsgObj_t *pObj, UInt32 period)
{
    pObj->prd.clkHandle = BspOsal_clockCreate(
                            (BspOsal_ClockFuncPtr)Utils_dcanPrdCalloutFcn,
                            period,
                            FALSE,
                            pObj
                            );
    UTILS_assert(pObj->prd.clkHandle != NULL);

    BspOsal_clockStart(pObj->prd.clkHandle);

    pObj->prd.clkStarted = TRUE;

    return;

}

/**
  *****************************************************************************
  * \brief Delete prd object
  *
  *****************************************************************************
*/
static Void Utils_dcanDeletePrdObj(dcanTxMsgObj_t * pObj)
{
    /* Stop the clock */
    BspOsal_clockStop(pObj->prd.clkHandle);
    BspOsal_clockDelete(&pObj->prd.clkHandle);
    pObj->prd.clkHandle = NULL;
    pObj->prd.clkStarted = FALSE;

    return;
}

static void Utils_dcanInitRxQueue(dcanRxMsgObj_t *dcanRxMsg)
{
    Int32 status;
    Int i;

    status =
        Utils_queCreate(&dcanRxMsg->freeQ.handle,
                        UTILS_ARRAYSIZE(dcanRxMsg->freeQ.queMem),
                        &dcanRxMsg->freeQ.queMem[0],
                        UTILS_QUE_FLAG_NO_BLOCK_QUE);
    UTILS_assert(0 == status);
    for ( i = 0; i < UTILS_ARRAYSIZE(dcanRxMsg->dcanQueMsgs);i++)
    {
        Utils_dcanQuePut(&dcanRxMsg->freeQ.handle,
                         &dcanRxMsg->dcanQueMsgs[i],
                         DCAN_MSG_STATE_IN_FREEQ);
    }
    for (i = 0; i < UTILS_ARRAYSIZE(dcanRxMsg->rxMsgQ);i++)
    {
        status =
            Utils_queCreate(&dcanRxMsg->rxMsgQ[i].handle,
                UTILS_ARRAYSIZE(dcanRxMsg->rxMsgQ[i].queMem),
                &dcanRxMsg->rxMsgQ[i].queMem[0],
                UTILS_QUE_FLAG_NO_BLOCK_QUE);
        UTILS_assert(0 == status);
    }
}

/**
  *****************************************************************************
  * \brief Deinitialize DCAN rx msg queue
  *
  *****************************************************************************
*/
static void Utils_dcanDeInitRxQueue(dcanRxMsgObj_t *dcanRxMsg)
{


    Int32 status;
    Int i;

    for (i = 0; i < UTILS_ARRAYSIZE(dcanRxMsg->rxMsgQ);i++)
    {
        status =
            Utils_queDelete(&dcanRxMsg->rxMsgQ[i].handle);
        UTILS_assert(0 == status);
    }
    status =
        Utils_queDelete(&dcanRxMsg->freeQ.handle);
    UTILS_assert(0 == status);
}

/**
  *****************************************************************************
  * \brief Wait for DCAN Tx Msg transmission completion
  *
  *****************************************************************************
*/
static void Utils_dcanWaitForTxComplete(UInt32 txMbxIndex)
{
    Bool semPendStatus;

    UTILS_assert(txMbxIndex < UTILS_ARRAYSIZE(dcanTxMsgObj.dcanTxMsgAckObj));
    UTILS_assert(dcanTxMsgObj.dcanTxMsgAckObj[txMbxIndex].semTxComplete != NULL);

    semPendStatus = BspOsal_semWait(dcanTxMsgObj.dcanTxMsgAckObj[txMbxIndex].semTxComplete,
                                BSP_OSAL_WAIT_FOREVER);
    UTILS_assert(semPendStatus == TRUE);
}

/**
  *****************************************************************************
  * \brief Write MSG to DCAN bus
  *
  *****************************************************************************
*/
static void Utils_dcanWrite(dcanTxParams_t *msg,UInt32 mbxId)
{
    IArg key;
    Int32 retVal;
    UInt32 mbxIndex;

    mbxIndex = Utils_dcanGetTxMbxIndex(mbxId);

    key = Utils_dcanTxMutexEnter();

	//Vps_printf(" Utils_dcanWaitForIfReg\n");
    Utils_dcanWaitForIfReg(UTILS_DCAN_INST, UTILS_DCAN_TX_IF_REG);
	//Vps_printf(" Utils_dcanWaitForIfReg end\n");

    retVal = DCANTransmitData(UTILS_DCAN_INST,
               mbxId,
               UTILS_DCAN_TX_IF_REG,
               msg,
               0);
    UTILS_assert(retVal == 0);
    /* Wait for config to be copied to internal message RAM */
    Utils_dcanWaitForIfReg(UTILS_DCAN_INST, UTILS_DCAN_TX_IF_REG);

	//Vps_printf(" Utils_dcanWaitForIfReg end\n");
    Utils_dcanWaitForTxComplete(mbxIndex);

//	Vps_printf(" Utils_dcanWaitForTxComplete end\n");
    Utils_dcanTxMutexLeave(key);
}

/**
  *****************************************************************************
  * \brief Initialize xmit completion related data structures
  *
  *****************************************************************************
*/
static void Utils_dcanInitTxAckObj(dcanTxMsgObj_t *dcanTxMsgObj)
{
    Int i;

    for (i = 0; i < UTILS_ARRAYSIZE(dcanTxMsgObj->dcanTxMsgAckObj); i++)
    {
        dcanTxMsgObj->dcanTxMsgAckObj[i].semTxComplete =
          BspOsal_semCreate(0, TRUE);
    }
}

/**
  *****************************************************************************
  * \brief Initialize critical section associated with DCAN msg xmit
  *
  *****************************************************************************
*/
static Void Utils_dcanInitGateObj(dcanIsrContext_t *dcanIsrContext)
{
    GateMutexPri_Params prms;

    GateMutexPri_Params_init(&prms);
    GateMutexPri_construct(&dcanIsrContext->mutexMem,&prms);
    dcanIsrContext->mutex =  GateMutexPri_handle(&dcanIsrContext->mutexMem);
}

/**
  *****************************************************************************
  * \brief DeInitialize critical section associated with DCAN msg xmit
  *
  *****************************************************************************
*/
static Void Utils_dcanDeInitGateObj(dcanIsrContext_t *dcanIsrContext)
{
    GateMutexPri_destruct(&dcanIsrContext->mutexMem);
    dcanIsrContext->mutex =  NULL;
}

/**
  *****************************************************************************
  * \brief Enter critical section associated with DCAN msg xmit
  *
  *****************************************************************************
*/
static IArg Utils_dcanTxMutexEnter()
{
    UTILS_assert(NULL != dcanIsrContext.mutex);

    return (GateMutexPri_enter(dcanIsrContext.mutex));
}

/**
  *****************************************************************************
  * \brief Leave critical section associated with DCAN msg xmit
  *
  *****************************************************************************
*/
static Void Utils_dcanTxMutexLeave(IArg key)
{
    UTILS_assert(NULL != dcanIsrContext.mutex);

    GateMutexPri_leave(dcanIsrContext.mutex,key);
}

/**
  *****************************************************************************
  * \brief Deintialize DCAN xmit msg completion related data structures
  *
  *****************************************************************************
*/
static void Utils_dcanDeInitTxAckObj(dcanTxMsgObj_t *dcanTxMsgObj)
{
    Int i;

    for (i = 0; i < UTILS_ARRAYSIZE(dcanTxMsgObj->dcanTxMsgAckObj); i++)
    {
        BspOsal_semDelete(&dcanTxMsgObj->dcanTxMsgAckObj[i].semTxComplete);
    }
}

/**
  *****************************************************************************
  * \brief DCAN RX Get mailbox index for the passed mailbox id
  *
  *****************************************************************************
*/
static UInt Utils_dcanGetRxMbxIndex(UInt32 mailBoxId)
{
    UInt i;

    for (i = 0; i < UTILS_ARRAYSIZE(dcanRxMbxId); i++)
    {
        if (dcanRxMbxId[i] == mailBoxId)
        {
            break;
        }
    }
    UTILS_assert(i < UTILS_ARRAYSIZE(dcanRxMbxId));
    return i;
}

/**
  *****************************************************************************
  * \brief DCAN TX Get mailbox index for the passed mailbox id
  *
  *****************************************************************************
*/
static UInt Utils_dcanGetTxMbxIndex(UInt32 mailBoxId)
{
    UInt i;

    for (i = 0; i < UTILS_ARRAYSIZE(dcanTxMbxId); i++)
    {
        if (dcanTxMbxId[i] == mailBoxId)
        {
            break;
        }
    }
    UTILS_assert(i < UTILS_ARRAYSIZE(dcanTxMbxId));
    return i;
}

/**
  *****************************************************************************
  * \brief DCAN rx msg callback
  *
  *****************************************************************************
*/
static Void Utils_dcanRxMsgProcess(dcanMsg_t *msg)
{
    if (dcanConfig.rxMsgCb)
    {
        dcanConfig.rxMsgCb(msg);
    }
}

/**
  *****************************************************************************
  * \brief Get msg id corresponding to passed mailboxId
  *
  *****************************************************************************
*/
static UInt32 Utils_dcanMapMailboxId2MsgId(UInt32 mailboxId)
{
    Int i;

    for (i = 0; i < UTILS_ARRAYSIZE(dcanMbx2MsgIdMap); i++)
    {
        if (dcanMbx2MsgIdMap[i].mbxId == mailboxId)
        {
            break;
        }
    }
    UTILS_assert(i < UTILS_ARRAYSIZE(dcanMbx2MsgIdMap));
    return dcanMbx2MsgIdMap[i].msgId;
}

/**
  *****************************************************************************
  * \brief Get mailbox id corresponding to passed msgId
  *
  *****************************************************************************
*/
static UInt32 Utils_dcanMapMsgId2MailboxId(UInt32 msgId)
{
    Int i;

    for (i = 0; i < UTILS_ARRAYSIZE(dcanMbx2MsgIdMap); i++)
    {
        if (dcanMbx2MsgIdMap[i].msgId == msgId)
        {
            break;
        }
    }
    UTILS_assert(i < UTILS_ARRAYSIZE(dcanMbx2MsgIdMap));
    return dcanMbx2MsgIdMap[i].mbxId;
}

/**
  *****************************************************************************
  * \brief Set msgId for specified mailbox
  *
  *****************************************************************************
*/
static Void Utils_dcanSetMailboxMsgId(UInt32 mailboxId,UInt32 msgId)
{
    Int i;

    for (i = 0; i < UTILS_ARRAYSIZE(dcanMbx2MsgIdMap); i++)
    {
        if (dcanMbx2MsgIdMap[i].mbxId == mailboxId)
        {
            break;
        }
    }
    UTILS_assert(i < UTILS_ARRAYSIZE(dcanMbx2MsgIdMap));
    dcanMbx2MsgIdMap[i].msgId = msgId;
}

/**
  *****************************************************************************
  * \brief Send Rx Ack msg
  *
  * Ack msg is copy of received msg with only msgId modified
  *****************************************************************************
*/
static Void Utils_dcanRxSendAckMsg(dcanMsg_t *rxMsg)
{
    dcanTxParams_t txAckParams;

    Utils_dcanInitTxMsgParams(&txAckParams,&rxMsg->appMsgPrms.msgData[0],
                              rxMsg->appMsgPrms.dataLength);

    Vps_printf(" Utils_dcanRxSendAckMsg\n");
    Utils_dcanWrite(&txAckParams,UTILS_DCAN_TX_ACK_MSG_OBJ);
}

/**
  *****************************************************************************
  * \brief Send periodic DCAN xmit msg
  *
  *****************************************************************************
*/
static Void Utils_dcanTxSendMsg()
{
    dcanTxParams_t txAckParams;
    Int i,j;

    for (i = 0; i < UTILS_ARRAYSIZE(dcanTxMbxId)-1; i++)
    {
        if (dcanConfig.enableTxMsgCycle)
         {
            for (j = 0; j < UTILS_ARRAYSIZE(dcanConfig.dcanTxPrdMsg.msgData); j++)
             {
                /*dcanConfig.dcanTxPrdMsg.msgData[j] =
                                (dcanConfig.dcanTxPrdMsg.msgData[j] + 1) % 256;*/
				dcanConfig.dcanTxPrdMsg.msgData[j] = j+1 ;
             }
         }
        Utils_dcanInitTxMsgParams(&txAckParams,&dcanConfig.dcanTxPrdMsg.msgData[0],
                                  UTILS_ARRAYSIZE(dcanConfig.dcanTxPrdMsg.msgData));
        Utils_dcanWrite(&txAckParams,dcanTxMbxId[i]);
    }
}

/**
  *****************************************************************************
  * \brief Dequeue and process any dcan rx msgs across all rx mailbox queues
  *
  *****************************************************************************
*/
static Void Utils_dcanRxProcessMailbox(dcanRxMsgObj_t * dcanRxMsg,
                                       UInt postedEvents)
{
    Int i;
    dcanMsg_t *rxMsg = NULL;
    struct dcanQueMsgs_s * queMsg = NULL;
	static Int no_ack_flag;
	no_ack_flag = 1;

    for (i = 0; i < UTILS_ARRAYSIZE(dcanRxMbxId) ; i++)
    {
         if (postedEvents & (0x1U << i))
         {
             while (Utils_queGetQueuedCount(&dcanRxMsg->rxMsgQ[i].handle))
             {
                 Utils_dcanQueGet(&dcanRxMsg->rxMsgQ[i].handle,
                                  &queMsg,
                                  &rxMsg,
                                  DCAN_MSG_STATE_IN_RX_QUE,
                                  DCAN_MSG_STATE_MSG_RX);
                 dcanRxMsg->state = DCAN_RX_TSK_STATE_RXMSGCALLBACK;
                 Utils_dcanRxMsgProcess(rxMsg);
				 if(no_ack_flag == 0)
				 {
			dcanRxMsg->state = DCAN_RX_TSK_STATE_RXACK;
			Utils_dcanRxSendAckMsg(rxMsg);
				 }
                 Utils_dcanQuePut(&dcanRxMsg->freeQ.handle,
                                  queMsg,
                                  DCAN_MSG_STATE_IN_FREEQ);
                 Utils_dcanConfigRxMsgObj(dcanRxMbxId[i]);
             }
         }
    }
}

/**
  *****************************************************************************
  * \brief DCAN RX thread handler function
  *
  *****************************************************************************
*/
static Void Utils_dcanRxTsk(UArg arg0, UArg arg1)
{
    dcanRxMsgObj_t *dcanRxMsg = (dcanRxMsgObj_t *)arg0;
    UInt32 mbxMask = dcanRxMsg->mbxMask;
    Bool exitLoop = FALSE;
    UInt postedEvents;

    mbxMask |= UTILS_DCAN_TSK_EXIT_EVENT;
    dcanRxMsg->state = DCAN_RX_TSK_STATE_START;

    do {
        dcanRxMsg->state = DCAN_RX_TSK_STATE_WAITEVENT;
        postedEvents = Event_pend(dcanRxMsg->dcanRxEvent,0,mbxMask,
                                  BSP_OSAL_WAIT_FOREVER);
        if (postedEvents & UTILS_DCAN_TSK_EXIT_EVENT)
        {
            exitLoop = TRUE;
        }
        else
        {
            Utils_dcanRxProcessMailbox(dcanRxMsg,postedEvents);

        }
    } while(exitLoop != TRUE);
    dcanRxMsg->state = DCAN_RX_TSK_STATE_STOP;
}

/**
  *****************************************************************************
  * \brief Initialize DCAN Rx thread
  *
  *****************************************************************************
*/
static void Utils_dcanInitRxThread(dcanRxMsgObj_t *dcanRxMsg,UInt32 mbxMask)
{
    Event_Params eventParams;

    Event_Params_init(&eventParams);
    Event_construct(&dcanRxMsg->dcanRxEventMem, &eventParams);
    dcanRxMsg->dcanRxEvent =  Event_handle(&dcanRxMsg->dcanRxEventMem);

    dcanRxMsg->mbxMask = mbxMask;
    dcanRxMsg->dcanRxTsk = BspOsal_taskCreate(
                                (BspOsal_TaskFuncPtr)Utils_dcanRxTsk,
                                "DCAN Rx Task",
                                dcanConfig.dcanRxTskPri,
                                &gUtilsDcanRx_tskStack[0],
                                sizeof(gUtilsDcanRx_tskStack),
                                dcanRxMsg,
                                UTILS_TSK_AFFINITY_CORE0
                                );

    UTILS_assert(dcanRxMsg->dcanRxTsk != NULL);
    Utils_prfLoadRegister(dcanRxMsg->dcanRxTsk, "DCANRX");
}

static UInt32 Utils_dcanResetRxAckMbxMask(UInt32 mbxMask)
{
    UInt rxAckMbxIndex;


    rxAckMbxIndex = Utils_dcanGetRxMbxIndex(UTILS_DCAN_RX_ACK_MSG_OBJ);
    return (mbxMask & ~(0x1U << rxAckMbxIndex));
}

/**
  *****************************************************************************
  * \brief Deinitialize DCAN Rx thread
  *
  *****************************************************************************
*/
static void Utils_dcanDeInitRxThread(dcanRxMsgObj_t *dcanRxMsg)
{
    Event_post(dcanRxMsg->dcanRxEvent,UTILS_DCAN_TSK_EXIT_EVENT);

    Utils_prfLoadUnRegister(dcanRxMsg->dcanRxTsk);

    BspOsal_taskDelete(&dcanRxMsg->dcanRxTsk);

    dcanRxMsg->dcanRxTsk = NULL;
}

/**
  *****************************************************************************
  * \brief Callback function to handle Rx Ack msg
  *
  *****************************************************************************
*/
static Void Utils_dcanTxMsgProcessAck(dcanMsg_t *rxMsg)
{
    if (dcanConfig.rxAckMsgCb)
    {
        dcanConfig.rxAckMsgCb(rxMsg);
    }
}

/**
  *****************************************************************************
  * \brief Rx ack msg handler function
  *
  *****************************************************************************
*/
static Void Utils_dcanTxHandleRxAck(dcanTxMsgObj_t *dcanTxMsg,
                                    UInt postedEvents)
{
    Int i;
    dcanMsg_t *rxMsg = NULL;
    struct dcanQueMsgs_s *queMsg;

    for (i = 0; i < UTILS_ARRAYSIZE(dcanRxMbxId) ; i++)
    {
         if (postedEvents & (0x1U << i))
         {
             Utils_dcanQueGet(dcanTxMsg->dcanRxAckQue,
                              &queMsg,
                              &rxMsg,
                              DCAN_MSG_STATE_IN_RX_QUE,
                              DCAN_MSG_STATE_MSG_RX_ACK);
             Utils_dcanTxMsgProcessAck(rxMsg);
             Utils_dcanQuePut(dcanTxMsg->dcanRxAckFreeQue,
                              queMsg,
                              DCAN_MSG_STATE_IN_FREEQ);
             Utils_dcanConfigRxMsgObj(dcanRxMbxId[i]);
         }
    }
}

/**
  *****************************************************************************
  * \brief DCAN periodic thread handler function
  *
  *****************************************************************************
*/

extern 	UInt32 rock_can_send_cmd ;
extern UInt32 rock_can_test_data_rec_cnt;
extern UInt32 rock_can_test_data_rec_err_cnt;

static Void Utils_dcanTxTsk(UArg arg0, UArg arg1)
{
    dcanTxMsgObj_t *dcanTxMsg = (dcanTxMsgObj_t *)arg0;
    Bool exitLoop = FALSE;
    UInt32 eventMask = 0;
    UInt postedEvents;
    UInt rxAckMbxIndex;
	UInt32 i = 0;
	static UInt32 can_tx_cnt = 0;
	static UInt32 task_cnt = 0;
	UInt rock_test_flag = 1;

    rxAckMbxIndex = Utils_dcanGetRxMbxIndex(UTILS_DCAN_RX_ACK_MSG_OBJ);
    eventMask |= UTILS_DCAN_TSK_EXIT_EVENT;
    eventMask |= UTILS_DCAN_TX_PRD_EVENT;
    dcanTxMsg->state = DCAN_TX_TSK_STATE_START;
  //  Vps_printf(" Utils_dcanTxTsk\n");

    do {
        dcanTxMsg->state = DCAN_TX_TSK_STATE_WAITEVENT;
        postedEvents = Event_pend(dcanTxMsg->dcanTxEvent,0,eventMask,
                                  BSP_OSAL_WAIT_FOREVER);
        if (postedEvents & UTILS_DCAN_TSK_EXIT_EVENT)
        {
            exitLoop = TRUE;
        }
        else
        {


//		Vps_printf(" Utils_dcanTxSendMsg start \n");
		if(rock_can_send_cmd == 1)
		{
			for(i=0;i < 100;i++)
			{
	            Utils_dcanTxSendMsg();
				can_tx_cnt++;
			}

		}
			task_cnt++;

			if(task_cnt >= 10)
			{
				task_cnt = 0;
				Vps_printf(" can_tx_cnt = %d \n",can_tx_cnt);
				Vps_printf(" rock_can_test_data_rec_cnt = %d \n",rock_can_test_data_rec_cnt);
				Vps_printf(" rock_can_test_data_rec_err_cnt = %d \n",rock_can_test_data_rec_err_cnt);
			}
//		Vps_printf(" Utils_dcanTxSendMsg end \n");
            postedEvents =
            Event_pend(dcanTxMsg->dcanRxAckEvent,
                       0,
                       (0x1U << rxAckMbxIndex),
                       0);

		if(rock_test_flag == 0)
		{
            if (postedEvents && dcanConfig.enableSendRxAck)
            {
                dcanTxMsg->state = DCAN_TX_TSK_STATE_PROCESSACK;
                Utils_dcanTxHandleRxAck(dcanTxMsg,postedEvents);
            }
            dcanTxMsg->state = DCAN_TX_TSK_STATE_SENDMSG;
            Utils_dcanTxSendMsg();
		}
//		Vps_printf(" Utils_dcanTxSendMsg end \n");
        }
    } while(exitLoop != TRUE);
    dcanTxMsg->state = DCAN_TX_TSK_STATE_STOP;
}


/**
  *****************************************************************************
  * \brief Initialize DCAN Tx thread
  *
  *****************************************************************************
*/
static void Utils_dcanInitTxThread(dcanTxMsgObj_t *dcanTxMsg)
{
    Event_Params eventParams;

    Event_Params_init(&eventParams);
    Event_construct(&dcanTxMsg->dcanTxEventMem, &eventParams);
    dcanTxMsg->dcanTxEvent =  Event_handle(&dcanTxMsg->dcanTxEventMem);


    dcanTxMsg->dcanTxTsk = BspOsal_taskCreate(
                                (BspOsal_TaskFuncPtr)Utils_dcanTxTsk,
                                "DCAN Tx Task",
                                dcanConfig.dcanTxTskPri,
                                &gUtilsDcanTx_tskStack[0],
                                sizeof(gUtilsDcanTx_tskStack),
                                dcanTxMsg,
                                UTILS_TSK_AFFINITY_CORE0
                            );

    UTILS_assert(dcanTxMsg->dcanTxTsk != NULL);
    Utils_prfLoadRegister(dcanTxMsg->dcanTxTsk, "DCANTX");
}

/**
  *****************************************************************************
  * \brief Deinitialize DCAN Tx thread
  *
  *****************************************************************************
*/
static void Utils_dcanDeInitTxThread(dcanTxMsgObj_t *dcanTxMsg)
{
    Event_post(dcanTxMsg->dcanTxEvent,UTILS_DCAN_TSK_EXIT_EVENT);

    Utils_prfLoadUnRegister(dcanTxMsg->dcanTxTsk);

    BspOsal_taskDelete(&dcanTxMsg->dcanTxTsk);

    dcanTxMsg->dcanTxTsk = NULL;
}

/**
  *****************************************************************************
  * \brief Platform related initialization of DCAN1 interface
  *
  * PRCM enabled for DCAN1 and setup pinumux for DCAN1 TX / RX pins
  *
  *****************************************************************************
*/
static Void Utils_dcanPlatformInit()
{
    /* DRM_SUSPEND_CTRL_DCAN1 - SUSPEND_SEL(Suspend source selection) as IPU1_C0
     * & SENS_CTRL(Sensitivity control) as 1 means suspend signal must reach the
     * peripheral-IP  */
    //HW_WR_REG32(DRM_SUSPEND_CTRL_DCAN1, ((DRM_SUSPEND_SRC_IPU1_C0 << 4) | 0x1));

    /*Unlock the Crossbar register */
    PlatformUnlockMMR();



#if ENABLE_DCAN1_FLAG
    /* Clock Configuration. */
    PlatformDCAN1PrcmEnable();

    /* Perform the DCAN pinmux. */
    PlatformDCAN1SetPinMux();

    /* Initialize the DCAN message RAM. */
    PlatformDcanMessageRamInit(0);
#endif


#if ENABLE_DCAN2_FLAG

		/* Clock Configuration. */
		  PlatformDCAN2PrcmEnable();
		/* Perform the DCAN pinmux. */
		  PlatformDCAN2SetPinMux();
		/* Initialize the DCAN message RAM. */
		  PlatformDcanMessageRamInit(1);
#endif

}

/**
  *****************************************************************************
  * \brief Intialize DCAN rx Mailbox config structure
  *
  *****************************************************************************
*/
static void Utils_dcanConfigRxMsgObj(UInt32 rxMailboxId)
{
    Int32               retVal    = STW_SOK;
    dcanMsgObjCfgParams_t appDcanRxCfgPrms;

    /* Wait for interface to become free */
    Utils_dcanWaitForIfReg(UTILS_DCAN_INST, UTILS_DCAN_RX_IF_REG);
    Utils_dcanInitRxMsgObjParams(&appDcanRxCfgPrms,
                                 Utils_dcanMapMailboxId2MsgId(rxMailboxId),FALSE);
    retVal = DCANConfigMsgObj(UTILS_DCAN_INST,
                              rxMailboxId,
                              UTILS_DCAN_RX_IF_REG,
                              &appDcanRxCfgPrms);
    UTILS_assert(retVal == 0);
    /* Wait for config to be copied to internal message RAM */
    Utils_dcanWaitForIfReg(UTILS_DCAN_INST, UTILS_DCAN_RX_IF_REG);
}

/**
  *****************************************************************************
  * \brief Intialize DCAN Rx thread
  *
  *****************************************************************************
*/
static void Utils_dcanInitRx()
{
    Int i;
    UInt32 mbxMask = 0;

    for (i = 0; i < UTILS_ARRAYSIZE(dcanRxMbxId); i++)
    {
        Utils_dcanConfigRxMsgObj(dcanRxMbxId[i]);
        mbxMask |= (0x1U << i);
    }
    Utils_dcanInitRxQueue(&dcanRxMsgObj);
    Utils_dcanInitRxThread(&dcanRxMsgObj,Utils_dcanResetRxAckMbxMask(mbxMask));
}


/**
  *****************************************************************************
  * \brief DeIntialize DCAN Rx thread
  *
  *****************************************************************************
*/
static void Utils_dcanDeInitRx()
{
    Utils_dcanDeInitRxThread(&dcanRxMsgObj);
    Utils_dcanDeInitRxQueue(&dcanRxMsgObj);
}

/**
  *****************************************************************************
  * \brief Intialize DCAN Rx ack related datasturctures
  *
  *****************************************************************************
*/
static void Utils_dcanTxInitAckInfo(dcanTxMsgObj_t *dcanTxMsgObj,
                                    dcanRxMsgObj_t *dcanRxMsgObj)
{
    UInt32 rxAckMbxIndex;

    rxAckMbxIndex = Utils_dcanGetRxMbxIndex(UTILS_DCAN_RX_ACK_MSG_OBJ);
    dcanTxMsgObj->dcanRxAckEvent = dcanRxMsgObj->dcanRxEvent;
    UTILS_assert(NULL != dcanTxMsgObj->dcanRxAckEvent);
    dcanTxMsgObj->dcanRxAckFreeQue = &dcanRxMsgObj->freeQ.handle;
    dcanTxMsgObj->dcanRxAckQue     = &dcanRxMsgObj->rxMsgQ[rxAckMbxIndex].handle;
}

/**
  *****************************************************************************
  * \brief Intialize DCAN TX prd object
  *
  *****************************************************************************
*/
static void Utils_dcanTxInitPrdObj(dcanTxMsgObj_t *dcanTxMsgObj)
{
    Utils_dcanCreatePrdObj(dcanTxMsgObj, dcanConfig.txMsgPeriod_ms);
}

/**
  *****************************************************************************
  * \brief DeIntialize DCAN TX prd object
  *
  *****************************************************************************
*/
static void Utils_dcanTxDeInitPrdObj(dcanTxMsgObj_t *dcanTxMsgObj)
{
    Utils_dcanDeletePrdObj(dcanTxMsgObj);
}

/**
  *****************************************************************************
  * \brief Intialize DCAN TX periodic thread
  *
  *****************************************************************************
*/
static void Utils_dcanInitTx()
{
    Int i;
    Int32               retVal    = STW_SOK;
    dcanMsgObjCfgParams_t appDcanTxCfgPrms;

    for (i = 0; i < UTILS_ARRAYSIZE(dcanTxMbxId); i++)
    {
        /* Wait for interface to become free */
        Utils_dcanWaitForIfReg(UTILS_DCAN_INST, UTILS_DCAN_TX_IF_REG);
        Utils_dcanInitTxMsgObjParams(&appDcanTxCfgPrms,
                                     Utils_dcanMapMailboxId2MsgId(dcanTxMbxId[i]),FALSE);
        retVal = DCANConfigMsgObj(UTILS_DCAN_INST,
                                  dcanTxMbxId[i],
                                  UTILS_DCAN_TX_IF_REG,
                                  &appDcanTxCfgPrms);
        UTILS_assert(retVal == 0);
        /* Wait for config to be copied to internal message RAM */
        Utils_dcanWaitForIfReg(UTILS_DCAN_INST, UTILS_DCAN_TX_IF_REG);
    }
    Utils_dcanInitTxAckObj(&dcanTxMsgObj);
    Utils_dcanTxInitAckInfo(&dcanTxMsgObj,&dcanRxMsgObj);
    if ((dcanConfig.enablePeriodicTx) || (dcanConfig.enableLoopback))
    {
        Utils_dcanTxInitPrdObj(&dcanTxMsgObj);
        Utils_dcanInitTxThread(&dcanTxMsgObj);
    }
}

/**
  *****************************************************************************
  * \brief DeIntialize DCAN TX periodic thread
  *
  *****************************************************************************
*/
static void Utils_dcanDeInitTx()
{
    if ((dcanConfig.enablePeriodicTx) || (dcanConfig.enableLoopback))
    {
        Utils_dcanDeInitTxThread(&dcanTxMsgObj);
        Utils_dcanTxDeInitPrdObj(&dcanTxMsgObj);
    }
    Utils_dcanDeInitTxAckObj(&dcanTxMsgObj);
}

/**
  *****************************************************************************
  * \brief Intialize default mapping between mailbox and msgid
  *
  *****************************************************************************
*/
static Void Utils_dcanInitDefaultMbx2MsgIdMap()
{
    dcanMbx2MsgIdMap[0].mbxId = UTILS_DCAN_RX_MSG_OBJ;
    dcanMbx2MsgIdMap[0].msgId = UTILS_DCAN_CTRL_MSG_ID;
    
    dcanMbx2MsgIdMap[1].mbxId = UTILS_DCAN_TX_MSG_OBJ;
    dcanMbx2MsgIdMap[1].msgId = UTILS_DCAN_CTRL_MSG_ID;
    
    dcanMbx2MsgIdMap[2].mbxId = UTILS_DCAN_RX_ACK_MSG_OBJ;
    dcanMbx2MsgIdMap[2].msgId = UTILS_DCAN_CTRL_ACK_MSG_ID;
    
    dcanMbx2MsgIdMap[3].mbxId = UTILS_DCAN_TX_ACK_MSG_OBJ;
    dcanMbx2MsgIdMap[3].msgId = UTILS_DCAN_CTRL_ACK_MSG_ID;

    dcanMbx2MsgIdMap[4].mbxId = UTILS_DCAN_RX_MSG_OBJ1;
    dcanMbx2MsgIdMap[4].msgId = UTILS_DCAN_CTRL_MSG_ID1;

    dcanMbx2MsgIdMap[5].mbxId = UTILS_DCAN_RX_MSG_OBJ2;
    dcanMbx2MsgIdMap[5].msgId = UTILS_DCAN_CTRL_MSG_ID2;

    dcanMbx2MsgIdMap[6].mbxId = UTILS_DCAN_RX_MSG_OBJ3;
    dcanMbx2MsgIdMap[6].msgId = UTILS_DCAN_CTRL_MSG_ID3;

    dcanMbx2MsgIdMap[7].mbxId = UTILS_DCAN_RX_MSG_OBJ4;
    dcanMbx2MsgIdMap[7].msgId = UTILS_DCAN_CTRL_MSG_ID4;

    dcanMbx2MsgIdMap[8].mbxId = UTILS_DCAN_RX_MSG_OBJ5;
    dcanMbx2MsgIdMap[8].msgId = UTILS_DCAN_CTRL_MSG_ID5;

    dcanMbx2MsgIdMap[9].mbxId = UTILS_DCAN_RX_MSG_OBJ6;
    dcanMbx2MsgIdMap[9].msgId = UTILS_DCAN_CTRL_MSG_ID6;

    dcanMbx2MsgIdMap[10].mbxId = UTILS_DCAN_RX_MSG_OBJ7;
    dcanMbx2MsgIdMap[10].msgId = UTILS_DCAN_CTRL_MSG_ID7;

    dcanMbx2MsgIdMap[11].mbxId = UTILS_DCAN_RX_MSG_OBJ8;
    dcanMbx2MsgIdMap[11].msgId = UTILS_DCAN_CTRL_MSG_ID8;

    dcanMbx2MsgIdMap[12].mbxId = UTILS_DCAN_RX_MSG_OBJ9;
    dcanMbx2MsgIdMap[12].msgId = UTILS_DCAN_CTRL_MSG_ID9;

    dcanMbx2MsgIdMap[13].mbxId = UTILS_DCAN_RX_MSG_OBJ10;
    dcanMbx2MsgIdMap[13].msgId = UTILS_DCAN_CTRL_MSG_ID10;

    dcanMbx2MsgIdMap[14].mbxId = UTILS_DCAN_RX_MSG_OBJ11;
    dcanMbx2MsgIdMap[14].msgId = UTILS_DCAN_CTRL_MSG_ID11;

    dcanMbx2MsgIdMap[15].mbxId = UTILS_DCAN_RX_MSG_OBJ12;
    dcanMbx2MsgIdMap[15].msgId = UTILS_DCAN_CTRL_MSG_ID12;

    dcanMbx2MsgIdMap[16].mbxId = UTILS_DCAN_RX_MSG_OBJ13;
    dcanMbx2MsgIdMap[16].msgId = UTILS_DCAN_CTRL_MSG_ID13;

    dcanMbx2MsgIdMap[17].mbxId = UTILS_DCAN_RX_MSG_OBJ14;
    dcanMbx2MsgIdMap[17].msgId = UTILS_DCAN_CTRL_MSG_ID14;

    dcanMbx2MsgIdMap[18].mbxId = UTILS_DCAN_RX_MSG_OBJ15;
    dcanMbx2MsgIdMap[18].msgId = UTILS_DCAN_CTRL_MSG_ID15;

    dcanMbx2MsgIdMap[19].mbxId = UTILS_DCAN_RX_MSG_OBJ16;
    dcanMbx2MsgIdMap[19].msgId = UTILS_DCAN_CTRL_MSG_ID16;

    dcanMbx2MsgIdMap[20].mbxId = UTILS_DCAN_RX_MSG_OBJ17;
    dcanMbx2MsgIdMap[20].msgId = UTILS_DCAN_CTRL_MSG_ID17;

    dcanMbx2MsgIdMap[21].mbxId = UTILS_DCAN_RX_MSG_OBJ18;
    dcanMbx2MsgIdMap[21].msgId = UTILS_DCAN_CTRL_MSG_ID18;

    dcanMbx2MsgIdMap[22].mbxId = UTILS_DCAN_RX_MSG_OBJ19;
    dcanMbx2MsgIdMap[22].msgId = UTILS_DCAN_CTRL_MSG_ID19;

    dcanMbx2MsgIdMap[23].mbxId = UTILS_DCAN_RX_MSG_OBJ20;
    dcanMbx2MsgIdMap[23].msgId = UTILS_DCAN_CTRL_MSG_ID20;

    dcanMbx2MsgIdMap[24].mbxId = UTILS_DCAN_RX_MSG_OBJ21;
    dcanMbx2MsgIdMap[24].msgId = UTILS_DCAN_CTRL_MSG_ID21;

    dcanMbx2MsgIdMap[25].mbxId = UTILS_DCAN_RX_MSG_OBJ22;
    dcanMbx2MsgIdMap[25].msgId = UTILS_DCAN_CTRL_MSG_ID22;

    dcanMbx2MsgIdMap[26].mbxId = UTILS_DCAN_RX_MSG_OBJ23;
    dcanMbx2MsgIdMap[26].msgId = UTILS_DCAN_CTRL_MSG_ID23;

    dcanMbx2MsgIdMap[27].mbxId = UTILS_DCAN_RX_MSG_OBJ24;
    dcanMbx2MsgIdMap[27].msgId = UTILS_DCAN_CTRL_MSG_ID24;

    dcanMbx2MsgIdMap[28].mbxId = UTILS_DCAN_RX_MSG_OBJ25;
    dcanMbx2MsgIdMap[28].msgId = UTILS_DCAN_CTRL_MSG_ID25;

    dcanMbx2MsgIdMap[29].mbxId = UTILS_DCAN_RX_MSG_OBJ26;
    dcanMbx2MsgIdMap[29].msgId = UTILS_DCAN_CTRL_MSG_ID26;

    dcanMbx2MsgIdMap[30].mbxId = UTILS_DCAN_RX_MSG_OBJ27;
    dcanMbx2MsgIdMap[30].msgId = UTILS_DCAN_CTRL_MSG_ID27;

    dcanMbx2MsgIdMap[31].mbxId = UTILS_DCAN_RX_MSG_OBJ28;
    dcanMbx2MsgIdMap[31].msgId = UTILS_DCAN_CTRL_MSG_ID28;

    dcanMbx2MsgIdMap[32].mbxId = UTILS_DCAN_RX_MSG_OBJ29;
    dcanMbx2MsgIdMap[32].msgId = UTILS_DCAN_CTRL_MSG_ID29;

    dcanMbx2MsgIdMap[33].mbxId = UTILS_DCAN_RX_MSG_OBJ30;
    dcanMbx2MsgIdMap[33].msgId = UTILS_DCAN_CTRL_MSG_ID30;

    dcanMbx2MsgIdMap[34].mbxId = UTILS_DCAN_RX_MSG_OBJ31;
    dcanMbx2MsgIdMap[34].msgId = UTILS_DCAN_CTRL_MSG_ID31;

    dcanMbx2MsgIdMap[35].mbxId = UTILS_DCAN_RX_MSG_OBJ32;
    dcanMbx2MsgIdMap[35].msgId = UTILS_DCAN_CTRL_MSG_ID32;

    dcanMbx2MsgIdMap[36].mbxId = UTILS_DCAN_RX_MSG_OBJ33;
    dcanMbx2MsgIdMap[36].msgId = UTILS_DCAN_CTRL_MSG_ID33;

    dcanMbx2MsgIdMap[37].mbxId = UTILS_DCAN_RX_MSG_OBJ34;
    dcanMbx2MsgIdMap[37].msgId = UTILS_DCAN_CTRL_MSG_ID34;

    dcanMbx2MsgIdMap[38].mbxId = UTILS_DCAN_RX_MSG_OBJ35;
    dcanMbx2MsgIdMap[38].msgId = UTILS_DCAN_CTRL_MSG_ID35;

    dcanMbx2MsgIdMap[39].mbxId = UTILS_DCAN_RX_MSG_OBJ36;
    dcanMbx2MsgIdMap[39].msgId = UTILS_DCAN_CTRL_MSG_ID36;

    dcanMbx2MsgIdMap[40].mbxId = UTILS_DCAN_RX_MSG_OBJ37;
    dcanMbx2MsgIdMap[40].msgId = UTILS_DCAN_CTRL_MSG_ID37;

    dcanMbx2MsgIdMap[41].mbxId = UTILS_DCAN_RX_MSG_OBJ38;
    dcanMbx2MsgIdMap[41].msgId = UTILS_DCAN_CTRL_MSG_ID38;

    dcanMbx2MsgIdMap[42].mbxId = UTILS_DCAN_RX_MSG_OBJ39;
    dcanMbx2MsgIdMap[42].msgId = UTILS_DCAN_CTRL_MSG_ID39;

    dcanMbx2MsgIdMap[43].mbxId = UTILS_DCAN_RX_MSG_OBJ40;
    dcanMbx2MsgIdMap[43].msgId = UTILS_DCAN_CTRL_MSG_ID40;

    dcanMbx2MsgIdMap[44].mbxId = UTILS_DCAN_RX_MSG_OBJ41;
    dcanMbx2MsgIdMap[44].msgId = UTILS_DCAN_CTRL_MSG_ID41;

    dcanMbx2MsgIdMap[45].mbxId = UTILS_DCAN_RX_MSG_OBJ42;
    dcanMbx2MsgIdMap[45].msgId = UTILS_DCAN_CTRL_MSG_ID42;

    dcanMbx2MsgIdMap[46].mbxId = UTILS_DCAN_RX_MSG_OBJ43;
    dcanMbx2MsgIdMap[46].msgId = UTILS_DCAN_CTRL_MSG_ID43;

    dcanMbx2MsgIdMap[47].mbxId = UTILS_DCAN_RX_MSG_OBJ44;
    dcanMbx2MsgIdMap[47].msgId = UTILS_DCAN_CTRL_MSG_ID44;

    dcanMbx2MsgIdMap[48].mbxId = UTILS_DCAN_RX_MSG_OBJ45;
    dcanMbx2MsgIdMap[48].msgId = UTILS_DCAN_CTRL_MSG_ID45;

    dcanMbx2MsgIdMap[49].mbxId = UTILS_DCAN_RX_MSG_OBJ46;
    dcanMbx2MsgIdMap[49].msgId = UTILS_DCAN_CTRL_MSG_ID46;

    dcanMbx2MsgIdMap[50].mbxId = UTILS_DCAN_RX_MSG_OBJ47;
    dcanMbx2MsgIdMap[50].msgId = UTILS_DCAN_CTRL_MSG_ID47;

    dcanMbx2MsgIdMap[51].mbxId = UTILS_DCAN_RX_MSG_OBJ48;
    dcanMbx2MsgIdMap[51].msgId = UTILS_DCAN_CTRL_MSG_ID48;

    dcanMbx2MsgIdMap[52].mbxId = UTILS_DCAN_RX_MSG_OBJ49;
    dcanMbx2MsgIdMap[52].msgId = UTILS_DCAN_CTRL_MSG_ID49;

    dcanMbx2MsgIdMap[53].mbxId = UTILS_DCAN_RX_MSG_OBJ50;
    dcanMbx2MsgIdMap[53].msgId = UTILS_DCAN_CTRL_MSG_ID50;

    dcanMbx2MsgIdMap[54].mbxId = UTILS_DCAN_RX_MSG_OBJ51;
    dcanMbx2MsgIdMap[54].msgId = UTILS_DCAN_CTRL_MSG_ID51;

    dcanMbx2MsgIdMap[55].mbxId = UTILS_DCAN_RX_MSG_OBJ52;
    dcanMbx2MsgIdMap[55].msgId = UTILS_DCAN_CTRL_MSG_ID52;

    dcanMbx2MsgIdMap[56].mbxId = UTILS_DCAN_RX_MSG_OBJ53;
    dcanMbx2MsgIdMap[56].msgId = UTILS_DCAN_CTRL_MSG_ID53;

    dcanMbx2MsgIdMap[57].mbxId = UTILS_DCAN_RX_MSG_OBJ54;
    dcanMbx2MsgIdMap[57].msgId = UTILS_DCAN_CTRL_MSG_ID54;

    dcanMbx2MsgIdMap[58].mbxId = UTILS_DCAN_RX_MSG_OBJ55;
    dcanMbx2MsgIdMap[58].msgId = UTILS_DCAN_CTRL_MSG_ID55;

    dcanMbx2MsgIdMap[59].mbxId = UTILS_DCAN_RX_MSG_OBJ56;
    dcanMbx2MsgIdMap[59].msgId = UTILS_DCAN_CTRL_MSG_ID56;

    dcanMbx2MsgIdMap[60].mbxId = UTILS_DCAN_RX_MSG_OBJ57;
    dcanMbx2MsgIdMap[60].msgId = UTILS_DCAN_CTRL_MSG_ID57;

    dcanMbx2MsgIdMap[61].mbxId = UTILS_DCAN_RX_MSG_OBJ58;
    dcanMbx2MsgIdMap[61].msgId = UTILS_DCAN_CTRL_MSG_ID58;

    dcanMbx2MsgIdMap[62].mbxId = UTILS_DCAN_RX_MSG_OBJ59;
    dcanMbx2MsgIdMap[62].msgId = UTILS_DCAN_CTRL_MSG_ID59;

    dcanMbx2MsgIdMap[63].mbxId = UTILS_DCAN_RX_MSG_OBJ60;
    dcanMbx2MsgIdMap[63].msgId = UTILS_DCAN_CTRL_MSG_ID60;

    dcanMbx2MsgIdMap[64].mbxId = UTILS_DCAN_RX_MSG_OBJ61;
    dcanMbx2MsgIdMap[64].msgId = UTILS_DCAN_CTRL_MSG_ID61;

    dcanMbx2MsgIdMap[65].mbxId = UTILS_DCAN_RX_MSG_OBJ62;
    dcanMbx2MsgIdMap[65].msgId = UTILS_DCAN_CTRL_MSG_ID62;

    dcanMbx2MsgIdMap[66].mbxId = UTILS_DCAN_RX_MSG_OBJ63;
    dcanMbx2MsgIdMap[66].msgId = UTILS_DCAN_CTRL_MSG_ID63;

}



/**
  *****************************************************************************
  * \brief Intialize Utils_dcan global structures
  *
  *****************************************************************************
*/
static Void Utils_dcanInitStruct()
{
    Utils_dcanInitDefaultMbx2MsgIdMap();
    memset(&dcanTxMsgObj,0,sizeof(dcanTxMsgObj));
    memset(&dcanRxMsgObj,0,sizeof(dcanRxMsgObj));
    memset(&dcanIsrContext,0,sizeof(dcanIsrContext));
    dcanIsrContext.rxMsgObj = &dcanRxMsgObj;
    dcanIsrContext.txMsgObj = &dcanTxMsgObj;


}


/**
  *****************************************************************************
  * \brief Intialize default values for DCAN tx msg
  *
  *****************************************************************************
*/
static void Utils_dcanInitTxMsgParams(dcanTxParams_t        *pDcanTxPrms,
                                      UInt8 *msgData,
                                      UInt8 length)
{
    Int i;

    /*Intialize DCAN Tx transfer Params*/
    pDcanTxPrms->dataLength  = length;
    for (i = 0; i < length;i++)
    {
        pDcanTxPrms->msgData[i]  = msgData[i];
    }
}

/**
  *****************************************************************************
  * \brief Intialize default values for DCAN rx mailbox configuration
  *
  * \param pDcanRxCfgPrms Config params rx mailbox intialization
  * \param msgId Message Id asscoiated with the mailbox
  *
  *****************************************************************************
*/
static void Utils_dcanInitRxMsgObjParams(dcanMsgObjCfgParams_t *pDcanRxCfgPrms,
                                         UInt32 msgId,UInt32 msgType)
{
    /*Intialize DCAN Rx Config Params*/
    pDcanRxCfgPrms->xIdFlagMask       = 0x1;
    pDcanRxCfgPrms->dirMask           = 0x1;
    pDcanRxCfgPrms->msgIdentifierMask = 0x1FFFFFFF;

    pDcanRxCfgPrms->msgValid      = TRUE;
    pDcanRxCfgPrms->xIdFlag       = msgType;
    pDcanRxCfgPrms->direction     = DCAN_DIR_RX;
    if (FALSE == pDcanRxCfgPrms->xIdFlag)
    {
        msgId = (msgId & 0x7FF) << 18;
    }
    pDcanRxCfgPrms->msgIdentifier = msgId;

    pDcanRxCfgPrms->uMaskUsed    = FALSE;//TRUE;
    pDcanRxCfgPrms->intEnable    = TRUE;
    pDcanRxCfgPrms->remoteEnable = FALSE;

    pDcanRxCfgPrms->fifoEOBFlag  = TRUE;

}

/**
  *****************************************************************************
  * \brief Intialize default values for DCAN tx mailbox configuration
  *
  * \param pDcanTxCfgPrms Config params tx mailbox intialization
  * \param msgId Message Id asscoiated with the mailbox
  *
  *****************************************************************************
*/
static void Utils_dcanInitTxMsgObjParams(dcanMsgObjCfgParams_t *pDcanTxCfgPrms,
                                         UInt32 msgId,UInt32 msgType)
{
    /*Intialize DCAN tx Config Params*/
    pDcanTxCfgPrms->xIdFlagMask       = 0x1;
    pDcanTxCfgPrms->dirMask           = 0x1;
    pDcanTxCfgPrms->msgIdentifierMask = 0x1FFFFFFF;

    pDcanTxCfgPrms->msgValid      = TRUE;
    pDcanTxCfgPrms->xIdFlag       = msgType;
    pDcanTxCfgPrms->direction     = DCAN_DIR_TX;
    if (FALSE == pDcanTxCfgPrms->xIdFlag)
    {
        msgId = (msgId & 0x7FF) << 18;
    }
    pDcanTxCfgPrms->msgIdentifier = msgId;

    pDcanTxCfgPrms->uMaskUsed    = TRUE;
    pDcanTxCfgPrms->intEnable    = TRUE;
    pDcanTxCfgPrms->remoteEnable = FALSE;

    pDcanTxCfgPrms->fifoEOBFlag  = TRUE;
}


/**
  *****************************************************************************
  * \brief DCAN controller configuration default params initialization
  *
  * \param pDcanCfgPrms Config params to intialize
  *
  *****************************************************************************
*/
static void Utils_dcanInitControllerParams(dcanCfgParams_t       *pDcanCfgPrms)
{
    /*Intialize DCAN Config Params*/
    pDcanCfgPrms->parityEnable          = FALSE;
    pDcanCfgPrms->autoRetransmitDisable = TRUE;
    pDcanCfgPrms->autoBusOnEnable       = FALSE;
    pDcanCfgPrms->intrLine0Enable       = FALSE;
    pDcanCfgPrms->intrLine1Enable       = TRUE;
    pDcanCfgPrms->errIntrEnable         = FALSE;
    pDcanCfgPrms->stsChangeIntrEnable   = FALSE;
#ifdef TDA3XX_FAMILY_BUILD
    pDcanCfgPrms->eccModeEnable = FALSE;
#endif
    pDcanCfgPrms->autoBusOnTimerVal = FALSE;
    if (dcanConfig.enableLoopback)
    {
        pDcanCfgPrms->testModeEnable    = TRUE;
        pDcanCfgPrms->testMode          = DCAN_TEST_MODE_EXT_LPBACK;
    }
    else
    {
        pDcanCfgPrms->testModeEnable    = FALSE;
        pDcanCfgPrms->testMode          = DCAN_TEST_MODE_NONE;
    }
    pDcanCfgPrms->if1DmaEnable      = FALSE;
    pDcanCfgPrms->if2DmaEnable      = FALSE;
    pDcanCfgPrms->if3DmaEnable      = FALSE;
    pDcanCfgPrms->ramAccessEnable   = FALSE;
}

/**
 * \brief   This function takes I/P Clk frequency, required bit-rate on the
 *          CAN bus and calculates the value to be programmed for DCAN BTR
 *          register. This API doesn't to 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 Hz.
 * \param   bitRate        Required bit-rate on the CAN bus in bits per second.
 * \param   pBitTimePrms   Pointer to params where the calculated register
 *                         fields are populated
 *
 * \return  errVal         Returns Bit Time calculation error of type enum
 *                         dcanBitTimeCalcErrType_t
 */
static UInt32 Utils_dcanCalculateBitTimeParams(UInt32             clkFreq,
                                                 UInt32             bitRate,
                                                 dcanBitTimeParams_t *pBitTimePrms)
{
    UInt32 errVal;
    dcanBitTimeParamsLocal_t bitTimePrms;

    bitTimePrms.samplePnt           = 0U;
    bitTimePrms.timeQuanta          = 0U;
    bitTimePrms.propSeg             = 0U;
    bitTimePrms.phaseSeg1           = 0U;
    bitTimePrms.phaseSeg2           = 0U;
    bitTimePrms.syncJumpWidth       = 0U;
    bitTimePrms.bitRatePrescaler    = 0U;
    bitTimePrms.tseg1Min            = 1U;
    bitTimePrms.tseg1Max            = 16U;
    bitTimePrms.tseg2Min            = 1U;
    bitTimePrms.tseg2Max            = 8U;
    bitTimePrms.syncJumpWidthMax    = 4U;
    bitTimePrms.bitRatePrescalerMin = 1U;
    bitTimePrms.bitRatePrescalerMax = 1024U;
    bitTimePrms.bitRatePrescalerInc = 1U;
    bitTimePrms.bitRate             = bitRate;

    errVal = Utils_dcanBitTimeCalculator(&bitTimePrms, clkFreq);

    pBitTimePrms->baudRatePrescaler =
        ((bitTimePrms.bitRatePrescaler - 1U) & DCAN_BTR_BRP_MASK);
    pBitTimePrms->syncJumpWidth = bitTimePrms.syncJumpWidth;
    pBitTimePrms->timeSegment1  =
        (bitTimePrms.phaseSeg1 + bitTimePrms.propSeg - 1U);
    pBitTimePrms->timeSegment2         = (bitTimePrms.phaseSeg2 - 1U);
    pBitTimePrms->baudRatePrescalerExt =
        (((bitTimePrms.bitRatePrescaler -
           1U) & UTILS_DCAN_EXTRACT_BRPE_VAL) >> UTILS_DCAN_BRPE_SHIFT);

    return (errVal);
}

/**
  *****************************************************************************
  * \brief DCAN bit timing calcuation related function
  *
  *****************************************************************************
*/
static UInt32 Utils_dcanBitTimeCalculator(
    dcanBitTimeParamsLocal_t *pBitTimeParam,
    UInt32                  clkFreq)
{
    Int32  samplePnt = 0U, samplePntErr = 1000U, tsegAll = 0U;
    Int32  tseg      = 0U, tseg1 = 0U, tseg2 = 0U;
    Int32  brp       = 0U, samplePntNew = 0U, bestTseg = 0U, bestBrp = 0U;
    Long   err       = 0U, bestErr = 1000000000U;
    UInt32 errVal    = DCAN_BIT_RATE_ERR_NONE;
    UInt32 rate      = 0U, timeQuanta = 0U;

    if (pBitTimeParam->bitRate > 800000U)
    {
        samplePnt = 750U;
    }
    else if (pBitTimeParam->bitRate > 500000U)
    {
        samplePnt = 800U;
    }
    else
    {
        samplePnt = 875U;
    }

    for (tseg = (pBitTimeParam->tseg1Max + pBitTimeParam->tseg2Max) * 2 + 1;
         tseg >= (pBitTimeParam->tseg1Min + pBitTimeParam->tseg2Min) * 2;
         tseg--)
    {
        tsegAll = 1 + tseg / 2;

        /* Compute all possible tseg choices (tseg = tseg1+tseg2) */
        brp = clkFreq / (tsegAll * pBitTimeParam->bitRate) + tseg % 2;

        /* chose brp step which is possible in system */
        brp = (brp / pBitTimeParam->bitRatePrescalerInc) *
              pBitTimeParam->bitRatePrescalerInc;

        if ((brp < pBitTimeParam->bitRatePrescalerMin) ||
            (brp > pBitTimeParam->bitRatePrescalerMax))
        {
            continue;
        }

        rate = clkFreq / (brp * tsegAll);
        err  = pBitTimeParam->bitRate - rate;

        /* tseg brp biterror */
        if (err < 0)
        {
            err = -err;
        }
        if (err > bestErr)
        {
            continue;
        }
        bestErr = err;
        if (err == 0)
        {
            samplePntNew = Utils_dcanUpdateSamplePnt(pBitTimeParam,
                                                  samplePnt,
                                                  tseg / 2,
                                                  &tseg1,
                                                  &tseg2);

            err = samplePnt - samplePntNew;
            if (err < 0)
            {
                err = -err;
            }
            if (err > samplePntErr)
            {
                continue;
            }
            samplePntErr = err;
        }
        bestTseg = tseg / 2;
        bestBrp  = brp;
        if (err == 0)
        {
            break;
        }
    }

    if (bestErr)
    {
        /* Error in one-tenth of a percent */
        err = (bestErr * 1000) / pBitTimeParam->bitRate;
        if (err > UTILS_DCAN_CALC_MAX_ERROR)
        {
            errVal = DCAN_BIT_RATE_ERR_MAX;
        }
        else
        {
            errVal = DCAN_BIT_RATE_ERR_WARN;
        }
    }

    /* real sample point */
    pBitTimeParam->samplePnt = Utils_dcanUpdateSamplePnt(pBitTimeParam,
                                                      samplePnt,
                                                      bestTseg,
                                                      &tseg1,
                                                      &tseg2);

    /* Calculate the time quanta value. */
    timeQuanta = bestBrp * 1000000000UL;

    pBitTimeParam->timeQuanta       = timeQuanta;
    pBitTimeParam->propSeg          = tseg1 / 2;
    pBitTimeParam->phaseSeg1        = tseg1 - pBitTimeParam->propSeg;
    pBitTimeParam->phaseSeg2        = tseg2;
    pBitTimeParam->syncJumpWidth    = 1;
    pBitTimeParam->bitRatePrescaler = bestBrp;

    /* Real bit-rate */
    pBitTimeParam->bitRate =
        clkFreq / (pBitTimeParam->bitRatePrescaler * (tseg1 + tseg2 + 1));

    return (errVal);
}

/**
  *****************************************************************************
  * \brief DCAN bit timing calcuation related function
  *
  *****************************************************************************
*/
static Int32 Utils_dcanUpdateSamplePnt(dcanBitTimeParamsLocal_t *pBitTimeParam,
                                      Int32                   samplePnt,
                                      Int32                   tseg,
                                      Int32                  *tseg1,
                                      Int32                  *tseg2)
{
    *tseg2 = tseg + 1 - (samplePnt * (tseg + 1)) / 1000;

    if (*tseg2 < pBitTimeParam->tseg2Min)
    {
        *tseg2 = pBitTimeParam->tseg2Min;
    }

    if (*tseg2 > pBitTimeParam->tseg2Max)
    {
        *tseg2 = pBitTimeParam->tseg2Max;
    }

    *tseg1 = tseg - *tseg2;

    if (*tseg1 > pBitTimeParam->tseg1Max)
    {
        *tseg1 = pBitTimeParam->tseg1Max;
        *tseg2 = tseg - *tseg1;
    }
    return (1000 * (tseg + 1 - *tseg2) / (tseg + 1));
}

/**
  *****************************************************************************
  * \brief Register the dcan controller interrupt handler
  *
  * \param  NONE
  *
  * \return NONE
  *****************************************************************************
*/
static void Utils_dcanConfigIntr(void)
{

    UInt32 cookie = 0;
    const UInt32 intrId = dcanConfig.dcanCntrlIntrId;

    IntXbar_connectIRQ(intrId, DCAN1_IRQ_INT1);
 //   IntXbar_connectIRQ(intrId, DCAN2_IRQ_INT1);

    /* Disabling the global interrupts */
    cookie = Hwi_disable();

    Vps_printf(" UTILS: DCAN INTERRUPT: HWI Create for INT%d !!!\n", intrId);

    dcanIsrContext.hwi = BspOsal_registerIntr(intrId,
                                    (BspOsal_IntrFuncPtr)Utils_dcanInt1Isr,
                                    &dcanIsrContext
                                    );

    if( dcanIsrContext.hwi == NULL)
    {
        Vps_printf(" UTILS: DCAN INTERRUPT: HWI Create Failed !!!\n");
        UTILS_assert(0);
    }

    /* Enable the interrupt */
    Hwi_enableInterrupt(intrId);

    /* Restore interrupts */
    Hwi_restore(cookie);

}

/**
  *****************************************************************************
  * \brief Unregister the dcan interrupt handler
  *
  * \param  NONE
  *
  * \return NONE
  *****************************************************************************
*/
static void Utils_dcanUnRegisterIntr(void)
{
    UInt32 cookie = 0;
    const UInt32 intrId = dcanConfig.dcanCntrlIntrId;

    /* Disabling the global interrupts */
    cookie = Hwi_disable();

    /* Enable the interrupt */
    Hwi_disableInterrupt(intrId);

    BspOsal_unRegisterIntr(&dcanIsrContext.hwi);

    /* Restore interrupts */
    Hwi_restore(cookie);

    IntXbar_disconnectIRQ(intrId);
}

/**
  *****************************************************************************
  * \brief Initialize DCAN Rx Msg structure
  *
  * \param  rxMsg         Pointer to dcan rx msg stucure
  *
  * \return NONE
  *****************************************************************************
*/
static void Utils_dcanResetRxMsg(dcanMsg_t *rxMsg)
{
    rxMsg->appMsgPrms.dataLength  = 0;
}

/**
  *****************************************************************************
  * \brief DCAN1 controller ISR receive specific handling
  *
  * \param  dcanRxMsgObj  Pointer to recv msg obj
  * \param  mbxId         Recv mailbox id
  * \param  rxMbxIndex    Recv mailbox index
  *
  * \return NONE
  *****************************************************************************
*/
static void Utils_dcanRxIsrCb(dcanRxMsgObj_t *dcanRxMsgObj,
                              UInt32 mbxId,
                              UInt32 rxMbxIndex)
{

    dcanMsg_t *rxMsg = NULL;
    struct dcanQueMsgs_s * queMsg = NULL;
    Int32 retVal;

    /* Get free can rx msg  */
    Utils_dcanQueGet(&dcanRxMsgObj->freeQ.handle,
                     &queMsg,
                     &rxMsg,
                     DCAN_MSG_STATE_IN_FREEQ,
                     DCAN_MSG_STATE_ISR);
    Utils_dcanResetRxMsg(rxMsg);

    /* Wait for interface to become free */
    Utils_dcanWaitForIfReg(UTILS_DCAN_INST, UTILS_DCAN_RX_IF_REG);
    /* Get data from CAN mailbox */
    retVal = DCANGetData(UTILS_DCAN_INST,
                         mbxId,
                         UTILS_DCAN_RX_IF_REG,
                         &rxMsg->appMsgPrms,
                         0);
    UTILS_assert(retVal == 0);
    Utils_dcanConfigRxMsgObj(mbxId);
    /* Copy CAN RX msg to free  msg  */
    rxMsg->msgId = Utils_dcanMapMailboxId2MsgId(mbxId);
    UTILS_assert(rxMbxIndex < UTILS_ARRAYSIZE(dcanRxMsgObj->rxMsgQ));
    /* Put received  msg into CAN RX mailbox specific queue */
    Utils_dcanQuePut(&dcanRxMsgObj->rxMsgQ[rxMbxIndex].handle,
                     queMsg,
                     DCAN_MSG_STATE_IN_RX_QUE);
    UTILS_assert(rxMbxIndex < UTILS_ARRAYSIZE(dcanRxMbxId));
    Event_post(dcanRxMsgObj->dcanRxEvent,(0x1U << rxMbxIndex));
}

/**
  *****************************************************************************
  * \brief DCAN1 controller ISR transmit specific handling
  *
  * \param  dcanTxMsgObj  Pointer to xmit msg obj
  * \param  txMbxIndex    Xmit mailbox index
  *
  * \return NONE
  *****************************************************************************
*/
static void Utils_dcanTxIsrCb(dcanTxMsgObj_t *dcanTxMsgObj,
                              UInt32 txMbxIndex)
{
    UTILS_assert(txMbxIndex < UTILS_ARRAYSIZE(dcanTxMsgObj->dcanTxMsgAckObj));
    BspOsal_semPost(dcanTxMsgObj->dcanTxMsgAckObj[txMbxIndex].semTxComplete);
}

/**
  *****************************************************************************
  * \brief DCAN1 controller interrupt handler
  *
  * \param  ctx      Pointer to DCAN controller ISR context
  *
  * \return NONE
  *****************************************************************************
*/
static void Utils_dcanInt1Isr(UArg ctx)
{
    Int i;
    dcanIsrContext_t *dcanIsrCtx = (dcanIsrContext_t *)ctx;

    for (i = 0; i < UTILS_ARRAYSIZE(dcanTxMbxId);i++)
    {
        if ((DCANIsMsgObjIntrPending(UTILS_DCAN_INST, dcanTxMbxId[i])) == TRUE)
        {
            Utils_dcanWaitForIfReg(UTILS_DCAN_INST, UTILS_DCAN_TX_IF_REG);
            /* Clear the interrupts  of MSG_OBJ 1 for transmit */
            DCANIntrClearStatus(UTILS_DCAN_INST, dcanTxMbxId[i],
                                UTILS_DCAN_TX_IF_REG);
            Utils_dcanWaitForIfReg(UTILS_DCAN_INST, UTILS_DCAN_TX_IF_REG);
            Utils_dcanTxIsrCb(dcanIsrCtx->txMsgObj,i);
        }
    }
    for (i = 0; i < UTILS_ARRAYSIZE(dcanRxMbxId);i++)
    {
        if ((DCANIsMsgObjIntrPending(UTILS_DCAN_INST, dcanRxMbxId[i])) == TRUE)
        {
            Utils_dcanWaitForIfReg(UTILS_DCAN_INST, UTILS_DCAN_RX_IF_REG);
            /* Clear the interrupts  of MSG_OBJ 2 for Receive */
            DCANIntrClearStatus(UTILS_DCAN_INST, dcanRxMbxId[i],
                                UTILS_DCAN_RX_IF_REG);
            Utils_dcanWaitForIfReg(UTILS_DCAN_INST, UTILS_DCAN_RX_IF_REG);
            Utils_dcanRxIsrCb(dcanIsrCtx->rxMsgObj,dcanRxMbxId[i],i);
        }
    }
}

/**
  *****************************************************************************
  * \brief Wait for DCAN interface regiter to become free
  *
  * \param  baseAddr DCAN IFREG base address
  * \param  ifRegNum DCAN interface register number
  *
  * \return NONE
  *****************************************************************************
*/
static void Utils_dcanWaitForIfReg(UInt32 baseAddr, UInt32 ifRegNum)
{
    do
    {
        if (TRUE != DCANIsIfRegBusy(baseAddr, ifRegNum))
        {
            break;
        }
    }
    while (1);
}

/**
  *****************************************************************************
  * \brief Intialize DCAN mailbox to msgid mapping
  *
  * \param  NONE
  * \return NONE
  *****************************************************************************
*/
static Void Utils_dcanInitMbx2MsgIdMap()
{
    if ((dcanConfig.enablePeriodicTx) || (dcanConfig.enableLoopback))
    {
        Utils_dcanSetMailboxMsgId(UTILS_DCAN_TX_MSG_OBJ,dcanConfig.txMsgId);
        if (dcanConfig.enableLoopback)
        {
            dcanConfig.rxMsgId = dcanConfig.txMsgId;
        }
    }
    if (dcanConfig.enableSendRxAck)
    {
        Utils_dcanSetMailboxMsgId(UTILS_DCAN_TX_ACK_MSG_OBJ,dcanConfig.txAckMsgId);
        if (dcanConfig.enableLoopback)
        {
            Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_ACK_MSG_OBJ,
                                      dcanConfig.txAckMsgId);
        }
    }

    if (dcanConfig.enableReceiveRxAck && !dcanConfig.enableLoopback)
    {
        Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_ACK_MSG_OBJ,
                                  dcanConfig.rxAckMsgId);
    }

    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ,dcanConfig.rxMsgId);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ1,dcanConfig.rxMsgId1);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ2,dcanConfig.rxMsgId2);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ3,dcanConfig.rxMsgId3);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ4,dcanConfig.rxMsgId4);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ5,dcanConfig.rxMsgId5);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ6,dcanConfig.rxMsgId6);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ7,dcanConfig.rxMsgId7);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ8,dcanConfig.rxMsgId8);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ9,dcanConfig.rxMsgId9);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ10,dcanConfig.rxMsgId10);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ11,dcanConfig.rxMsgId11);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ12,dcanConfig.rxMsgId12);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ13,dcanConfig.rxMsgId13);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ14,dcanConfig.rxMsgId14);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ15,dcanConfig.rxMsgId15);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ16,dcanConfig.rxMsgId16);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ17,dcanConfig.rxMsgId17);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ18,dcanConfig.rxMsgId18);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ19,dcanConfig.rxMsgId19);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ20,dcanConfig.rxMsgId20);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ21,dcanConfig.rxMsgId21);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ22,dcanConfig.rxMsgId22);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ23,dcanConfig.rxMsgId23);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ24,dcanConfig.rxMsgId24);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ25,dcanConfig.rxMsgId25);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ26,dcanConfig.rxMsgId26);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ27,dcanConfig.rxMsgId27);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ28,dcanConfig.rxMsgId28);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ29,dcanConfig.rxMsgId29);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ30,dcanConfig.rxMsgId30);   
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ31,dcanConfig.rxMsgId31);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ32,dcanConfig.rxMsgId32);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ33,dcanConfig.rxMsgId33);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ34,dcanConfig.rxMsgId34);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ35,dcanConfig.rxMsgId35);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ36,dcanConfig.rxMsgId36);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ37,dcanConfig.rxMsgId37);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ38,dcanConfig.rxMsgId38);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ39,dcanConfig.rxMsgId39);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ40,dcanConfig.rxMsgId40);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ41,dcanConfig.rxMsgId41);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ42,dcanConfig.rxMsgId42);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ43,dcanConfig.rxMsgId43);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ44,dcanConfig.rxMsgId44);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ45,dcanConfig.rxMsgId45);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ46,dcanConfig.rxMsgId46);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ47,dcanConfig.rxMsgId47);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ48,dcanConfig.rxMsgId48);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ49,dcanConfig.rxMsgId49);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ50,dcanConfig.rxMsgId50);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ51,dcanConfig.rxMsgId51);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ52,dcanConfig.rxMsgId52);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ53,dcanConfig.rxMsgId53);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ54,dcanConfig.rxMsgId54);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ55,dcanConfig.rxMsgId55);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ56,dcanConfig.rxMsgId56);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ57,dcanConfig.rxMsgId57);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ58,dcanConfig.rxMsgId58);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ59,dcanConfig.rxMsgId59);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ60,dcanConfig.rxMsgId60);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ61,dcanConfig.rxMsgId61);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ62,dcanConfig.rxMsgId62);
    Utils_dcanSetMailboxMsgId(UTILS_DCAN_RX_MSG_OBJ63,dcanConfig.rxMsgId63);
}

/**
  *****************************************************************************
  * \brief Initialize DCAN interface
  *
  * \param  dcanCfg Configuration structure used to initialize DCAN interface
  * \return NONE
  *****************************************************************************
*/
Void Utils_dcanInit(dcanConfig_t *dcanCfg)//called by system_dcan.c
{
    Int32 retVal    = STW_SOK;
    Int32 errStatus = STW_SOK;
    dcanBitTimeParams_t   appDcanBitTimePrms;
    dcanCfgParams_t       appDcanCfgPrms;
    Int i = 0;

    UTILS_COMPILETIME_ASSERT(UTILS_ARRAYSIZE(dcanMbx2MsgIdMap) ==
                             (UTILS_ARRAYSIZE(dcanRxMbxId) +
                              UTILS_ARRAYSIZE(dcanTxMbxId)));
                              
    if (FALSE == dcanInitDone)
    {
        dcanConfig = *dcanCfg;
        Utils_dcanInitStruct();
        Utils_dcanInitMbx2MsgIdMap();

        Utils_dcanPlatformInit();
        /* Register Crossbars and IRQ numbers */
        Utils_dcanConfigIntr();

        Utils_dcanInitGateObj(&dcanIsrContext);
        /* Reset the DCAN IP */
        retVal = DCANReset(UTILS_DCAN_INST, BSP_OSAL_WAIT_FOREVER);
        if (retVal == STW_SOK)
        {
            /* Set the desired bit rate based on input clock */
            DCANSetMode(UTILS_DCAN_INST, DCAN_MODE_INIT);
            errStatus = Utils_dcanCalculateBitTimeParams(dcanConfig.dcanInputClk_hz,
                                                   dcanConfig.dcanBaudRate_hz,
                                                   &appDcanBitTimePrms);
            UTILS_assert (errStatus == DCAN_BIT_RATE_ERR_NONE);
            DCANSetBitTime(UTILS_DCAN_INST, &appDcanBitTimePrms);
            DCANSetMode(UTILS_DCAN_INST, DCAN_MODE_NORMAL);

            /* Configure DCAN controller */
            Utils_dcanInitControllerParams(&appDcanCfgPrms);

            DCANConfig(UTILS_DCAN_INST, &appDcanCfgPrms);

        }

        if (retVal == STW_SOK)
        {
            Utils_dcanInitRx();
        }

        if (retVal == STW_SOK)
        {
            Utils_dcanInitTx();
        }
       if(retVal == STW_SOK)
       {
           /*
            * Enable message object interrupt to route interrupt line 1
            */
          for (i = 0; i < UTILS_ARRAYSIZE(dcanMbx2MsgIdMap); i++)
          {
             DCANConfigIntrMux(UTILS_DCAN_INST,
                               DCAN_INTR_LINE_NUM_1,
                           dcanMbx2MsgIdMap[i].mbxId);
          }
       }
       dcanInitDone = TRUE;
    }
}

/**
  *****************************************************************************
  * \brief Deinitialize DCAN interface
  *
  * \param  NONE
  * \return NONE
  *****************************************************************************
*/
Void Utils_dcanDeInit(void)
{
    if (dcanInitDone)
    {
        Utils_dcanDeInitTx();
        Utils_dcanDeInitRx();
        Utils_dcanDeInitGateObj(&dcanIsrContext);
        Utils_dcanUnRegisterIntr();
        dcanInitDone = FALSE;
    }
}

/**
  *****************************************************************************
  * \brief Write DCAN msg
  *
  * \param msg Message to be written to DCAN bus
  * \return NONE
  *****************************************************************************
*/
void Utils_dcanWriteMsg(dcanMsg_t *msg)
{
    Utils_dcanWrite(&msg->appMsgPrms,
                    Utils_dcanMapMsgId2MailboxId(msg->msgId));
}

