/**********************************************************************************************************************
 *  COPYRIGHT
 *  -------------------------------------------------------------------------------------------------------------------
 *  \verbatim
 *
 *                 TEXAS INSTRUMENTS INCORPORATED PROPRIETARY INFORMATION
 *
 *                 Property of Texas Instruments, Unauthorized reproduction and/or distribution
 *                 is strictly prohibited.  This product  is  protected  under  copyright  law
 *                 and  trade  secret law as an  unpublished work.
 *                 (C) Copyright Texas Instruments.  All rights reserved.
 *
 *  \endverbatim
 *  -------------------------------------------------------------------------------------------------------------------
 * 
 *  ------------------------------------------------------------------------------------------------------------------
 *  FILE DESCRIPTION
 *  -------------------------------------------------------------------------------------------------------------------
 *         File:  can.c
 *    Component:  Tms570_AutosarCanDriver
 *       Module:  DrvCan
 *    Generator:  -
 *
 *  Description:  The CAN driver is responsible for controlling the CAN module. Provides API's for transmission and
 *                reception of the data over CAN module
 * 
 *---------------------------------------------------------------------------------------------------------------------
 * Author:  Vishwanath Reddy
 *---------------------------------------------------------------------------------------------------------------------
 * Revision History
 *---------------------------------------------------------------------------------------------------------------------
 * Version        Date         Author               Change ID        Description
 *---------------------------------------------------------------------------------------------------------------------
 * 02.10.00       10Feb2013    Vishwanath Reddy    0000000000000    Initial Version adapted from TMS570LS31xx v1.10.00 
 * 02.10.02		  16Apr2013	   Vishwanath Reddy    SDOCM00100667 	Fixed CAN mask reception issues.
 * 02.20.00       23Aug2013    Vishwanath Reddy    SDOCM00103097    BusOff handling issue fix.
 *                                                 SDOCM00103356    Version info updated.
 *                                                                  Safety Requirements implemented.
 *                                                                  Added register structure from can_cfg.h file.
 *                                                                  Added API's Can_CheckWriteDet, Can_CheckEnableDet,
 *                                                                  Can_CheckSetControllerModeDet,Can_CheckWakeupDet,
 *                                                                  Can_ChangeBaudrateDet,Can_CheckBaudrateDet,
 *                                                                  Can_CheckDisableDet for better module granularity.
 *                                                                  Removed DET from ISR.
 *                                                                  Updated Can_EnableControllerInterrupts.
 *                                                                  Added requirement tags for tracebility.
 * 02.20.01       10Apr2014    Vishwanath Reddy    SDOCM00107321    Version Info update. 
 *                                                                  Add design tags.
 *                                                                  CAN_BAUD_RATE_CHECK_CHANGE_API modified to 
 *                                                                  CAN_CHANGE_BAUDRATE_API. 
 *                                                                  Fix for Missing frame at high bus load.   
 *                                                                  Fix for Remote frame reception.
 *                                                                  EcuM_CheckWakeup is called only if corresponding 
 *                                                                  WAKEUP_SOURCE_REF_x is defined.
 *                                                                  Update Can_CheckWriteDet to check if PduInfo->sdu
 *                                                                  is a NULL pointer.
 *                                                                  Update Can_Write to remove check of PduInfo->sdu.
 *                                                 SDOCM00107383    Disable Automatic Retransmission.
 * 02.21.00       30Sep2014    Vineeth T Alex      SDOCM00113179    Changes for Production release.
 *                                                                  Device compatibility.
 *                                                                  Automatic Retransmission Enabled by default.
 * 02.21.01       03Nov2014    Vineeth T Alex      SDOCM00113685    Support for cancellation of pending messages
 *                                                                  when Can moves to Start state.
 * 02.21.02       01Mar2016    Vishwanath Reddy    SDOCM00121479    Bugfix for "CAN does not receive messages after   
 *                                                                  busoff in interrupt mode". Can_Start API modified.
 *                                                 SDOCM00121669    Bugfix for "CAN does not receive the message 
 *                                                                  configured in the last message box of a node"
 * 02.30.00       01Dec2016    Sudhakar Singh           None        Update version info
 * 05.30.00       15Mar2017    Sudhakar Singh       SDOCM00122834    Version supports TMS570LSxx Family of Devices.
 *********************************************************************************************************************/
/**********************************************************************************************************************
 *  INCLUDES
 *********************************************************************************************************************/

#include "Can.h"
#include "CanIf_Cbk.h"
#include "EcuM_Cbk.h"
#include "Os.h"
/* SourceId : CAN_SourceId_005 */
/* DesignId : CAN_DesignId_003*/
/* Requirements : AR_CAN_SR29 */
#include "SchM_Can.h"

/* SourceId : CAN_SourceId_004 */
/* DesignId : CAN_DesignId_003*/
/* Requirements : AR_CAN_SR26 */
#if (CAN_DEV_ERROR_DETECT == STD_ON)
#include "Det.h"
#endif

/**********************************************************************************************************************
 *  VERSION CHECK
 *********************************************************************************************************************/
#define CAN_SW_C_MAJOR_VERSION               (5U)
#define CAN_SW_C_MINOR_VERSION               (30U)
#define CAN_SW_C_PATCH_VERSION               (0U)
 
 /* AUTOSAR version information check has to match definition in header file */
/* SourceId : CAN_SourceId_019 */
/* DesignId : CAN_DesignId_001 */
/* Requirements : AR_CAN_SR127 */
#if (  (CAN_AR_RELEASE_MAJOR_VERSION    != (0x04U)) \
    || (CAN_AR_RELEASE_MINOR_VERSION    != (0x00U)) \
    || (CAN_AR_RELEASE_REVISION_VERSION != (0x03U)) )
#error "CAN: AUTOSAR Version Numbers of CAN are different"
#endif

#if (  (CAN_SW_MAJOR_VERSION != CAN_SW_C_MAJOR_VERSION) || \
       (CAN_SW_MINOR_VERSION != CAN_SW_C_MINOR_VERSION) )
#error "Vendor specific version numbers of Can.c and Can.h are inconsistent"
#endif

#if (  (CAN_CFG_MAJOR_VERSION != CAN_SW_C_MAJOR_VERSION) || \
       (CAN_CFG_MINOR_VERSION != CAN_SW_C_MINOR_VERSION) )
#error "Version numbers of Can.c and Can_Cfg.h are inconsistent!"
#endif

/**********************************************************************************************************************
 *  STATIC CHECKS
 *********************************************************************************************************************/
/* FMEA requirement */
#if (STD_OFF == CAN_SRAM_PARITY_ENABLE)
	#warn "CAN parity check is not enabled "
#endif

/**********************************************************************************************************************
 *  TYPE DEFINITIONS
 *********************************************************************************************************************/
 
/* Register structure */
typedef volatile struct
{
  uint32      CTL;               /**< 0x0000: Control Register                       */
  uint32      ES;                /**< 0x0004: Error and Status Register              */
  uint32      EERC;              /**< 0x0008: Error Counter Register                 */
  uint32      BTR;               /**< 0x000C: Bit Timing Register                    */
  uint32      INT;               /**< 0x0010: Interrupt Register                     */
  uint32      TEST;              /**< 0x0014: Test Register                          */
  uint32      Reserved01;        /**< 0x0018: Reserved                               */
  uint32      PERR;              /**< 0x001C: Parity/SECDED Error Code Register      */
  uint32      REL;               /**< 0x0020: Core Release Register                  */
  uint32      ECCDIAG;           /**< 0x0024: ECC Diagnostic Register                */
  uint32      ECCDIADSTAT;       /**< 0x0028: ECC Diagnostic Status Register         */
  uint32      ECCCS;		     /**< 0x002C: ECC Control and Status Register        */
  uint32      ECCSERR	;        /**< 0x0030: ECC Single Bit Error Code Register     */
  uint32      Reserved04;        /**< 0x0034: Reserved                               */
  uint32      Reserved05;        /**< 0x0038: Reserved                               */
  uint32      Reserved06;        /**< 0x003C: Reserved                               */
  uint32      Reserved07;        /**< 0x0040: Reserved                               */
  uint32      Reserved08;        /**< 0x0044: Reserved                               */
  uint32      Reserved09;        /**< 0x0048: Reserved                               */
  uint32      Reserved10;        /**< 0x004C: Reserved                               */
  uint32      Reserved11;        /**< 0x0050: Reserved                               */
  uint32      Reserved12;        /**< 0x0054: Reserved                               */
  uint32      Reserved13;        /**< 0x0058: Reserved                               */
  uint32      Reserved14;        /**< 0x005C: Reserved                               */
  uint32      Reserved15;        /**< 0x0060: Reserved                               */
  uint32      Reserved16;        /**< 0x0064: Reserved                               */
  uint32      Reserved17;        /**< 0x0068: Reserved                               */
  uint32      Reserved18;        /**< 0x006C: Reserved                               */
  uint32      Reserved19;        /**< 0x0070: Reserved                               */
  uint32      Reserved20;        /**< 0x0074: Reserved                               */
  uint32      Reserved21;        /**< 0x0078: Reserved                               */
  uint32      Reserved22;        /**< 0x007C: Reserved                               */
  uint32      ABOTR;             /**< 0x0080: Auto Bus On Time Register              */
  uint32      TXRQX;             /**< 0x0084: Transmission Request X Register        */
  uint32      TXRQx[4U];         /**< 0x0088-0x0094: Transmission Request Registers  */
  uint32      NWDATX;            /**< 0x0098: New Data X Register                    */
  uint32      NWDATx[4U];        /**< 0x009C-0x00A8: New Data Registers              */
  uint32      INTPNDX;           /**< 0x00AC: Interrupt Pending X Register           */
  uint32      INTPNDx[4U];       /**< 0x00B0-0x00BC: Interrupt Pending Registers     */
  uint32      MSGVALX;           /**< 0x00C0: Message Valid X Register               */
  uint32      MSGVALx[4U];       /**< 0x00C4-0x00D0: Message Valid Registers         */
  uint32      Reserved23;        /**< 0x00D4: Reserved                               */
  uint32      INTMUXx[4U];       /**< 0x00D8-0x00E4: Interrupt Multiplexer Registers */
  uint32      Reserved24;        /**< 0x00E8: Reserved                               */
  uint32      Reserved25;        /**< 0x00EC: Reserved                               */
  uint32      Reserved26;        /**< 0x00F0: Reserved                               */
  uint32      Reserved27;        /**< 0x00F4: Reserved                               */
  uint32      Reserved28;        /**< 0x00F8: Reserved                               */
  uint32      Reserved29;        /**< 0x00FC: Reserved                               */
  uint8       Reserved65;        /**< 0x0100: IF1 Command Register, Reserved         */
  uint8       IF1CMD;            /**< 0x0100: IF1 Command Register, Command          */
  uint8       IF1STAT;           /**< 0x0100: IF1 Command Register, Status           */
  uint8       IF1NO;             /**< 0x0100: IF1 Command Register, Msg Number       */
  uint32      IF1MSK;            /**< 0x0104: IF1 Mask Register                      */
  uint32      IF1ARB;            /**< 0x0108: IF1 Arbitration Register               */
  uint32      IF1MCTL;           /**< 0x010C: IF1 Message Control Register           */
  can_data    IF1DATx;
  uint32      Reserved30;        /**< 0x0118: Reserved                               */
  uint32      Reserved31;        /**< 0x011C: Reserved                               */
  uint8       Reserved66;        /**< 0x0120: IF2 Command Register, Reserved         */
  uint8       IF2CMD;            /**< 0x0120: IF2 Command Register, Command          */
  uint8       IF2STAT;           /**< 0x0120: IF2 Command Register, Status           */
  uint8       IF2NO;             /**< 0x0120: IF2 Command Register, Msg Number       */
  uint32      IF2MSK;            /**< 0x0124: IF2 Mask Register                      */
  uint32      IF2ARB;            /**< 0x0128: IF2 Arbitration Register               */
  uint32      IF2MCTL;           /**< 0x012C: IF2 Message Control Register           */
  can_data    IF2DATx;
  uint32      Reserved32;        /**< 0x0138: Reserved                               */
  uint32      Reserved64;        /**< 0x013C: Reserved                               */
  uint32      IF3OBS;            /**< 0x0140: IF3 Observation Register               */
  uint32      IF3MSK;            /**< 0x0144: IF3 Mask Register                      */
  uint32      IF3ARB;            /**< 0x0148: IF3 Arbitration Register               */
  uint32      IF3MCTL;           /**< 0x014C: IF3 Message Control Register           */
  can_data    IF3DATx;
  uint32      Reserved34;        /**< 0x0158: Reserved                               */
  uint32      Reserved35;        /**< 0x015C: Reserved                               */
  uint32      IF3UEy[4U];        /**< 0x0160-0x016C: IF3 Update Enable Registers     */
  uint32      Reserved36;        /**< 0x0170: Reserved                               */
  uint32      Reserved37;        /**< 0x0174: Reserved                               */
  uint32      Reserved38;        /**< 0x0178: Reserved                               */
  uint32      Reserved39;        /**< 0x017C: Reserved                               */
  uint32      Reserved40;        /**< 0x0180: Reserved                               */
  uint32      Reserved41;        /**< 0x0184: Reserved                               */
  uint32      Reserved42;        /**< 0x0188: Reserved                               */
  uint32      Reserved43;        /**< 0x018C: Reserved                               */
  uint32      Reserved44;        /**< 0x0190: Reserved                               */
  uint32      Reserved45;        /**< 0x0194: Reserved                               */
  uint32      Reserved46;        /**< 0x0198: Reserved                               */
  uint32      Reserved47;        /**< 0x019C: Reserved                               */
  uint32      Reserved48;        /**< 0x01A0: Reserved                               */
  uint32      Reserved49;        /**< 0x01A4: Reserved                               */
  uint32      Reserved50;        /**< 0x01A8: Reserved                               */
  uint32      Reserved51;        /**< 0x01AC: Reserved                               */
  uint32      Reserved52;        /**< 0x01B0: Reserved                               */
  uint32      Reserved53;        /**< 0x01B4: Reserved                               */
  uint32      Reserved54;        /**< 0x01B8: Reserved                               */
  uint32      Reserved55;        /**< 0x01BC: Reserved                               */
  uint32      Reserved56;        /**< 0x01C0: Reserved                               */
  uint32      Reserved57;        /**< 0x01C4: Reserved                               */
  uint32      Reserved58;        /**< 0x01C8: Reserved                               */
  uint32      Reserved59;        /**< 0x01CC: Reserved                               */
  uint32      Reserved60;        /**< 0x01D0: Reserved                               */
  uint32      Reserved61;        /**< 0x01D4: Reserved                               */
  uint32      Reserved62;        /**< 0x01D8: Reserved                               */
  uint32      Reserved63;        /**< 0x01DC: Reserved                               */
  uint32      TIOC;              /**< 0x01E0: TX IO Control Register                 */
  uint32      RIOC;              /**< 0x01E4: RX IO Control Register                 */
} CAN_ControllerRegMap;

typedef CAN_ControllerRegMap* CAN_ControllerRegMapPtr;

#if(STD_ON == CAN_SAFETI_API)
/*SAFETYMCUSW 25 D MR:8.7 <APPROVED> "Reason - This is used in other files by users"*/
Can_CanConfigReg Can_CanConfig;
#endif

/**********************************************************************************************************************
 *  LOCAL FUNCTION PROTOTYPES                                                                               
 *********************************************************************************************************************/
/* Loop counter  - static function */
static FUNC(uint8, CAN_CODE) LoopCounter(uint8 controller, uint8 source);
static inline void LoopCounterInitEnd(uint8 controller, uint8 source);
static void ConfigController(uint8 Controller);
static void Can_RxProcess(uint16 mb);
#if (CAN_DEV_ERROR_DETECT == STD_ON)
static boolean Can_CheckWriteDet(uint8 Hth, Can_PduInfoPtrType PduInfo);
static boolean Can_CheckEnableDet(uint8 Controller);
static boolean Can_CheckDisableDet(uint8 Controller);
static boolean Can_CheckSetControllerModeDet(uint8 Controller);
static boolean Can_CheckWakeupDet(uint8 Controller);
#if (CAN_CHANGE_BAUDRATE_API == STD_ON)
static boolean Can_ChangeBaudrateDet(uint8 Controller);
static boolean Can_CheckBaudrateDet(uint8 Controller);
#endif
#endif
static void Can_SetId(uint16 Hth1, CAN_ControllerRegMap* node, Can_PduInfoPtrType PduInfo);
static void Can_ConfigBaudRate(uint8 Controller,CAN_ControllerRegMap *node);
static void Can_SetUpMBArray(uint8 Controller,uint8 htrh);
static void Can_SetMBDirAndId(uint8 htrh, uint8 Controller,CAN_ControllerRegMap *node);
static boolean Can_Start(uint8 Controller, CAN_ControllerRegMap *node);
static boolean Can_Stop(uint8 Controller, CAN_ControllerRegMap *node);
static boolean Can_Sleep(uint8 Controller, CAN_ControllerRegMap *node);
static boolean Can_WkUp(uint8 Controller, CAN_ControllerRegMap *node);
/**********************************************************************************************************************
 *  CONSTANT MACRO DEFINITION
 *********************************************************************************************************************/
/*CTL REg Patterns */
#define LOOPBACK_INT_REG_BIT    (0x10U)
#define LOOPBACK_EXT_REG_BIT    (0x100U)
#define TEST_ENABLE_BIT         (0x80U)
#define PARITY_BITS             (0xAU)
#define PARITY_ENABLE_PATTERN   (0x01U)
#define PARITY_DISABLE_PATTERN  (0x05U)
#define ENABLE_INIT_BIT         (0x1U)
#define IE_0_ENABLE             (0x2U)
#define CCE_BIT                 (0x40U)
#define LOCAL_PD_BIT            (0x1000000U)
#define SIE                     (0x4U)
#define EIE                     (0x8U)
#define WUBA                    (0x2000000U)
#define ENABLE_SW_RESET         (0x8000U)
#define CLR_MSG_LOST			(0x00004000U)

/*IF Register patterns*/
#define BUSY                    (0x80U)
#define CLRINTPEND              (0x08U)
#define ENABLE_NORMAL_MODE      (0x87U)

/*STATUS register Pattern */
#define WAKEUP_PEND             (0x200U)
#define BUS_OFF					(0x00000080U)
#define PDA_BIT                 (0x400U)

/*IF-CTL reg pattern */
#define MSG_VAL_BIT             (0x80000000U)
#define CMD_PATTERN             (0xF8U)
#define DLC                     (0x08U)
#define ENABL_TX_INTERRUPT      (0x00000800U)
#define ENABL_RX_INTERRUPT      (0x00000400U)
#define ENABLE_UMASK            (0x00001000U)

#define CTL_PATTERN             (0x00000080U)

/* Interrupt Patterns */
#define ERROR_STATUS_INT_BIT    (0x8000U)

/* Controller Base address for ISR */
#define CAN_0_BASE_ADDR         (0xFFF7DC00U)
#define CAN_1_BASE_ADDR         (0xFFF7DE00U)
#define CAN_2_BASE_ADDR         (0xFFF7E000U)

/**********************************************************************************************************************
 * MACRO DEFINITIONS
 *********************************************************************************************************************/

/*SAFETYMCUSW 340 S MR:19.7 <APPROVED> "Function-like macro is required here."*/
#define Can_EnterCritical()     (SchM_Enter_Can_CAN_EXCLUSIVE_AREA_0())
/*SAFETYMCUSW 340 S MR:19.7 <APPROVED> "Function-like macro is required here."*/
#define Can_LeaveCritical()     (SchM_Exit_Can_CAN_EXCLUSIVE_AREA_0())


/**********************************************************************************************************************
 *  LOCAL DATA DEFINITIONS
 *********************************************************************************************************************/
 /*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#define CAN_START_SEC_VAR_NO_INIT_UNSPECIFIED
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"

VAR(Can_MbHTRHMapping_Type, CAN_VAR_NOINIT) CanMbMapping[KMAX_CONTROLLER][KMAX_MB_PER_CONTROLLER];
VAR(PduIdType, CAN_VAR_NOINIT) canTxRxPduId[KMAX_MAILBOXES];
VAR(Can_DriverStateType, CAN_VAR_NOINIT) can_State[KMAX_CONTROLLER];

/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#define CAN_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"


/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#define CAN_START_SEC_VAR_INIT_UNSPECIFIED
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"

/*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
static P2CONST( Can_ConfigType, AUTOMATIC, CAN_PBCFG) Can_ConfigPtr=NULL_PTR;

/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#define CAN_STOP_SEC_VAR_INIT_UNSPECIFIED
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"


/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#define CAN_START_SEC_VAR_NO_INIT_8
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"

VAR(boolean, CAN_VAR_NOINIT) CanBusOffRecoveryStatus[KMAX_CONTROLLER];
VAR(uint8, CAN_VAR_NOINIT) CanSduPtr[8U];
volatile VAR(uint8, CAN_VAR_NOINIT) canInterruptCounter[KMAX_CONTROLLER];
VAR(uint8, CAN_VAR_NOINIT) canTxRxStatus[KMAX_MAILBOXES];
#if (CAN_DEV_ERROR_DETECT == STD_ON)
static VAR(uint8, CAN_VAR_NOINIT) canFxnId;
#endif

/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#define CAN_STOP_SEC_VAR_NO_INIT_8
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"


/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#define CAN_START_SEC_VAR_NO_INIT_16
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"

VAR(uint16, CAN_VAR_NOINIT) CanHtrhMbMapping[KMAX_MB_PER_CONTROLLER*KMAX_CONTROLLER];
VAR(uint16, CAN_VAR_NOINIT) canBaud[KMAX_CONTROLLER];

/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#define CAN_STOP_SEC_VAR_NO_INIT_16
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"


/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#define CAN_START_SEC_VAR_NO_INIT_32
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"

/* Timeout counter for 3 controller and 2 sources*/
static VAR(uint32, CAN_VAR_NOINIT) canLoopTimeout[KMAX_CONTROLLER][2U];

/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#define CAN_STOP_SEC_VAR_NO_INIT_32
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"


/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#define CAN_START_SEC_VAR_INIT_32
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"

static const uint32 s_canByteOrder[8U] = { 3U, 2U, 1U, 0U, 7U, 6U, 5U, 4U };

/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#define CAN_STOP_SEC_VAR_INIT_32
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"


/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#define CAN_START_SEC_CODE  
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"

 /**********************************************************************************************************************
 *  LOCAL FUNCTION DEFINITIONS
 *********************************************************************************************************************/
 
/* Loop timer related inline function */
/*********************************************************************************************************************
 * LoopCounterInitEnd
 *********************************************************************************************************************/
/*! \brief     This function is for the loopcounter this will set the counter variable to 0 
 *
 *  \param[in]  controller  controller number
 *              source      Source which calls this function
 *
 *  \context    App
 *********************************************************************************************************************/
/*SAFETYMCUSW 69 S MR:3.4 <APPROVED> "Reason -  Pragma is required here for functions in ISR"*/
#pragma CODE_STATE(LoopCounterInitEnd, 32)
static inline void LoopCounterInitEnd(uint8 controller, uint8 source) {
	canLoopTimeout[controller][source] = 0U;
}

/**********************************************************************************************************************
 * Can_CheckWriteDet
 *********************************************************************************************************************/
/*! \brief      This function will check DET for WriteAPI.
 *
 *  \param[in]  uint8 Hth - Hardware Handle 
 *				Can_PduInfoPtrType PduInfo - pointer to pdu.
 *
 *  \context
 *********************************************************************************************************************/
#if (CAN_DEV_ERROR_DETECT == STD_ON)
static boolean Can_CheckWriteDet(uint8 Hth, Can_PduInfoPtrType PduInfo)
{
   boolean returnstatus = TRUE;
   
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/	
   if((Can_ConfigPtr == NULL_PTR) || ( PduInfo->sdu == NULL_PTR ))
   {
      /* Can config pointer is not valid */
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0U, (uint8)CAN_WRITE_ID, (uint8)CAN_E_PARAM_POINTER);
      returnstatus = FALSE;
   }
   else if (Can_ConfigPtr->MaxMbCnt <= Hth )
   {   
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0U, (uint8)CAN_WRITE_ID, (uint8)CAN_E_PARAM_POINTER);
      returnstatus = FALSE;
   }
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/	
   else if(PduInfo == NULL_PTR)
   {
      /* Can config pointer is not valid */
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0U, (uint8)CAN_WRITE_ID, (uint8)CAN_E_PARAM_POINTER);
      returnstatus = FALSE;	  
   }
   else if (PduInfo->length > 8U )
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0U, (uint8)CAN_WRITE_ID, (uint8)CAN_E_PARAM_DLC);
      returnstatus = FALSE;
   }
   else
   {
	  /* MISRA C Compliance */
   }   
   return returnstatus;
}
#endif

/**********************************************************************************************************************
 * Can_SetId
 *********************************************************************************************************************/
/*! \brief      This function will set the ID.
 *
 *  \param[in]  uint8 Controller Controller Number in the can hardware its 0-3
 *
 *  \context
 *********************************************************************************************************************/
static void Can_SetId(uint16 Hth1, CAN_ControllerRegMap* node, Can_PduInfoPtrType PduInfo)
{
	if( Can_ConfigPtr->MailBoxList[Hth1]->MBIdType == ( 0U ) )
	{
		/* Standard ID*/
		node->IF1ARB  |= ( PduInfo->id & 0x7FFU ) << 18U ;
	}
	else if( Can_ConfigPtr->MailBoxList[Hth1]->MBIdType == ( 1U ) )
	{
		/* Extended ID*/
		node->IF1ARB |= PduInfo->id & 0x1FFFFFFFU ;
	}
	else
	{
		/*Mixed ID */
		if((PduInfo->id & 0x80000000U) == (0x80000000U) )
		{
		   /* Extended ID*/
		   node->IF1ARB  |=  (1U << 30U);
		   node->IF1ARB |= PduInfo->id & 0x1FFFFFFFU ;
		}
		else
		{
		   /* Standard ID*/
		   node->IF1ARB  &=  ~(1U << 30U);
		   node->IF1ARB  |= ( PduInfo->id & 0x7FFU ) << 18U ;                
		}
	}
}

/**********************************************************************************************************************
 * ConfigController
 *********************************************************************************************************************/
/*! \brief      Configures a specific controller is a private function.
 *
 *  \param[in]  uint8 Controller -  The controller for which the configuration to be performed
 *
 *
 *
 *  \context
 *********************************************************************************************************************/
static void ConfigController(uint8 Controller)
{
   CAN_ControllerRegMap *node;   
   uint8 htrh;   
   uint8 loopResult;   

   /*SAFETYMCUSW 95S MR:11.1 <APPROVED> "Reason - To access Can controller registers "*/
   /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason -  Can_ConfigPtr is already checked for NULLPTR in INIT."*/
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   node =  (CAN_ControllerRegMap *)(Can_ConfigPtr->CanControllerList[Controller]->CntrAddr);
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   if(node != NULL_PTR)   
   {
      node->CTL |= (ENABLE_INIT_BIT);
      node->CTL |=  (ENABLE_SW_RESET); /*perform sw reset*/
      /*Goto Init Mode*/
#if (STD_ON == CAN_SRAM_PARITY_ENABLE)
      node->CTL = (PARITY_ENABLE_PATTERN << PARITY_BITS) | (CCE_BIT) | (ENABLE_INIT_BIT);
#else
      node->CTL &= 0xC3FFU;
      node->CTL = ( PARITY_DISABLE_PATTERN << PARITY_BITS ) | (CCE_BIT)  | (ENABLE_INIT_BIT);
#endif

      /* Interrupt is enabled only if either RX or TX is in Interrupt mode */
      /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason - TRUE is not part of CAN.This should be fixed outside CAN."*/
	  if((Can_ConfigPtr->CanControllerList[Controller]->RxInterrupt == TRUE) 
        /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason - TRUE is not part of CAN.This should be fixed outside CAN."*/
		|| (Can_ConfigPtr->CanControllerList[Controller]->TxInterrupt == TRUE))
      {
         node->CTL |=  (IE_0_ENABLE);
         node->CTL |=  ( EIE );/*Enable the Error interrupts */
      }

      /* Clear all pending error flags and reset current status - only reading clears the flags */
      node->ES =  node->ES;
      /* Assign interrupt level for messages */
      node->INTMUXx[0U] = 0x00000000U;
      node->INTMUXx[1U] = 0x00000000U;
      /* Setup auto bus on timer period */
      node->ABOTR = 0U;

      /* find out if there is change in the baud rate set */
	  Can_ConfigBaudRate(Controller,node);      
  
      /* Enable the automatic wakeup via bus  */
      if(Can_ConfigPtr->CanControllerList[Controller]->CanBusWakeupSupport == TRUE)
      {
         node->CTL |= (WUBA);
      }
	  else
      {
         node->CTL &= ~(WUBA);
      }

      /* Perform the initialization of the mailboxes */
      for(htrh = 0U;htrh < Can_ConfigPtr->MaxMbCnt; htrh++)
      {
         if(Can_ConfigPtr->MailBoxList[htrh]->Controller->ControllerId == Controller )
         {
            /* TX objects configure the IF1 register set usage...*/        
            {
               /* Read from the control structure and initialize the Message boxes accordingly */
               /* Initialize message 1*/
               LoopCounterInitEnd(Controller,(uint8)1U);
               do
               {
                  loopResult= LoopCounter(Controller,(uint8)1U);
                  /*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/	
			   }
			   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
			   /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
			   while((loopResult!=0U) && ((node->IF1STAT & BUSY) == BUSY)); /*Misra checks fix*/
               LoopCounterInitEnd(Controller,(uint8)1U);

               /*Set the ID according to the MB Type. Also set Direction of MB */
               Can_SetMBDirAndId(htrh, Controller, node);			   

               node->IF1MCTL |= CTL_PATTERN | DLC;
               node->IF1CMD  = CMD_PATTERN;
               node->IF1NO   = Can_ConfigPtr->MailBoxList[htrh]->HwHandle;
               /* Setup IF1 for data transmission    */
               LoopCounterInitEnd(Controller,(uint8)1U);
               do
               {
                 /*SAFETYMCUSW 91D MR:16.10 <APPROVED> "Reason - loopResult is used in while MACRO"*/
                 loopResult= LoopCounter(Controller,(uint8)1U);
                 /*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/	
			   }
			   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
			   /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
			   while((loopResult!=0U) && ((node->IF1STAT & BUSY) == BUSY)); /* Misra fixes*/
               LoopCounterInitEnd(Controller,(uint8)1U);
            }

            /*Setup the Mb Mapping array */
			Can_SetUpMBArray(Controller,htrh);            
         }
      }
      node->IF1CMD=0x00U;
      /* Leave configuration  mode  */
      node->CTL &= ~(CCE_BIT);
   }/*End of else (node == NULL_PTR)*/
}

/**********************************************************************************************************************
 * Can_SetMBDirAndId
 *********************************************************************************************************************/
/*! \brief      This function will configure the ID, mask and Direction for a mail box.
 *
 *  \param[in]  uint8 Controller -  The controller for which the state change needs to be performed/
 *  			uint8 htrh - Hardware Handle              
 *				CAN_ControllerRegMap *node - Pointer to register structure.
 *
 *
 *  \context
 *********************************************************************************************************************/
static void Can_SetMBDirAndId(uint8 htrh, uint8 Controller, CAN_ControllerRegMap *node)
{
	uint32 mask=0x1FFFFFFFU;
	
	if(Can_ConfigPtr->MailBoxList[htrh]->MBIdType == 0U )
	{
		/* Standard ID*/
		node->IF1ARB  = (Can_ConfigPtr->MailBoxList[htrh]->IDValue & 0x7FFU) << 18U ;
		mask = (Can_ConfigPtr->MailBoxList[htrh]->Mask->MaskValue& 0x7FFU) << 18U ;				  	
	}
	else
	{
		/* Extended ID*/
		node->IF1ARB  = Can_ConfigPtr->MailBoxList[htrh]->IDValue & 0x1FFFFFFFU ;                  
		mask = Can_ConfigPtr->MailBoxList[htrh]->Mask->MaskValue & 0x1FFFFFFFU ;				  
	}

	node->IF1MSK  = (((Can_ConfigPtr->MailBoxList[htrh]->MBIdType) & 0x01U)<<31U) 
				|(0x01U << 30U)| ((mask & 0x1FFFFFFFU) << 0U);

   if( Can_ConfigPtr->MailBoxList[htrh]->MBDir == 0U) /* if it is RX mailbox*/
   {
		/*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason - TRUE is not part of CAN.This should be fixed outside CAN."*/
		if(Can_ConfigPtr->CanControllerList[Controller]->RxInterrupt == TRUE )
		{
			node->IF1MCTL |= ENABL_RX_INTERRUPT;
		}
		/* Set MB to be full Can */
		node->IF1MCTL |= ENABLE_UMASK; /* Set the UMASK so that FULL RX CAN is supported */
		node->IF1ARB  |= (MSG_VAL_BIT) |((Can_ConfigPtr->MailBoxList[htrh]->MBIdType)<<30U) 
					  | ((Can_ConfigPtr->MailBoxList[htrh]->MBDir)<<29U);		
   }
   else /* if it is Tx mail box*/
   {
		/*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason - TRUE is not part of CAN.This should be fixed outside CAN."*/
		if( Can_ConfigPtr->CanControllerList[Controller]->TxInterrupt == TRUE )
		{
			node->IF1MCTL |= ENABL_TX_INTERRUPT;
		}
		node->IF1ARB  |=(((Can_ConfigPtr->MailBoxList[htrh]->MBIdType)<<30U)&0x40000000U) 
					  | ((Can_ConfigPtr->MailBoxList[htrh]->MBDir)<<29U);
   }
}
 
 
/**********************************************************************************************************************
 * Can_SetUpMBArray
 *********************************************************************************************************************/
/*! \brief      This function will configure the baud rate.
 *
 *  \param[in]  uint8 Controller -  The controller for which the state change needs to be performed/
 *              uint8 htrh - hardware Handle.
 *
 *
 *  \context
 *********************************************************************************************************************/
static void Can_SetUpMBArray(uint8 Controller, uint8 htrh) 
{
	if (Can_ConfigPtr->CanControllerList[Controller]->CntrAddr == CAN_0_BASE_ADDR) 
	{
		CanMbMapping[CONTROLLER_ID_0][Can_ConfigPtr->MailBoxList[htrh]->HwHandle] =	htrh;
	} 
	else if (Can_ConfigPtr->CanControllerList[Controller]->CntrAddr	== CAN_2_BASE_ADDR) 
	{
		CanMbMapping[CONTROLLER_ID_2][Can_ConfigPtr->MailBoxList[htrh]->HwHandle] =	htrh;
	}
	else 
	{
		CanMbMapping[CONTROLLER_ID_1][Can_ConfigPtr->MailBoxList[htrh]->HwHandle] =	htrh;
	}
	CanHtrhMbMapping[Can_ConfigPtr->MailBoxList[htrh]->CanObjectId] = htrh;
}


/**********************************************************************************************************************
 * Can_Start
 *********************************************************************************************************************/
/*! \brief      This function will start the CAN node.
 *
 *  \param[in]  uint8 Controller -  The controller for which the state change needs to be performed/
 *              CAN_ControllerRegMap *node - Pointer to Register structure.
 *
 *
 *  \context
 *********************************************************************************************************************/
static boolean Can_Start(uint8 Controller, CAN_ControllerRegMap *node)
{
	boolean status = FALSE;
	uint8 loopResult,htrh;
	uint32 Can_EsReg2;

#if (CAN_DEV_ERROR_DETECT == STD_ON)
	if(can_State[Controller]!=CAN_STOPPED)
	{
		(void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_SETCTR_ID, (uint8)CAN_E_TRANSITION);
	}
	else
#endif
	{
	     for(htrh = 0U;htrh < Can_ConfigPtr->MaxMbCnt; htrh++)
		 {
		      if(Can_ConfigPtr->MailBoxList[htrh]->Controller->ControllerId == Controller )
			  {
					/* Cancel pending messages only for Tx Mail boxes */
					if (Can_ConfigPtr->MailBoxList[htrh]->MBDir == 1U)
					{
					  /* Can is expecting an acknowledge message for the pending message. We can clear that now. */
					  canTxRxStatus[htrh] = 0U;

					  /* Wait for IF1 to be not busy */
					  LoopCounterInitEnd((uint8)CONTROLLER_ID_1,(uint8)0U);
					  do
					  {
						 /*SAFETYMCUSW 91D MR:16.10 <APPROVED> "Reason - loopResult is used in while MACRO"*/
						 loopResult= LoopCounter((uint8)CONTROLLER_ID_1,(uint8)0U);
						 /*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/
					   }
					   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
					   /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
					   while((loopResult!=0U) && ((node->IF1STAT & BUSY)== BUSY)); /*MISRA fixes*/
					   LoopCounterInitEnd((uint8)CONTROLLER_ID_1,(uint8)0U);

					   /* Cancel pending messages by clearing TxRqst bit */
					   node->IF1MCTL &= 0xFFFFFEFFU;
					   node->IF1CMD = (0x90U);
					   node->IF1NO  = Can_ConfigPtr->MailBoxList[htrh]->HwHandle;

					   /* Wait for IF1 to be not busy */
					   LoopCounterInitEnd((uint8)CONTROLLER_ID_1,(uint8)0U);
					   do
					   {
						  /*SAFETYMCUSW 91D MR:16.10 <APPROVED> "Reason - loopResult is used in while MACRO"*/
						  loopResult= LoopCounter((uint8)CONTROLLER_ID_1,(uint8)0U);
						  /*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/
						}
						/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
						/*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
						while((loopResult!=0U) && ((node->IF1STAT & BUSY)== BUSY)); /*MISRA fixes*/
						LoopCounterInitEnd((uint8)CONTROLLER_ID_1,(uint8)0U);
					}	
			  }
		   }


		/* Get back to operational mode */
		node->CTL &= ~(((CCE_BIT) | (ENABLE_INIT_BIT)));
		/*Wait for INIT bit to be reset successfully*/
		LoopCounterInitEnd(Controller,(uint8)1U);
		do
		{
			/*SAFETYMCUSW 91D MR:16.10 <APPROVED> "Reason - loopResult is used in while MACRO"*/
			loopResult= LoopCounter(Controller,(uint8)1U);
			/*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/	
			/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - Volatile variable usage is required here since we wait
			  for INIT bit to be set "*/
			/*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason - Volatile variable usage is required here since we wait
			  for INIT bit to be set "*/  
		}while((loopResult!=0U) && ((node->CTL & (ENABLE_INIT_BIT)) == (ENABLE_INIT_BIT))); 
		LoopCounterInitEnd(Controller,(uint8)1U);
		can_State[Controller] = CAN_STARTED;
		CanIf_ControllerModeIndication( Controller, CANIF_CS_STARTED );
		status = TRUE;		
		/* Check if there is a busoff */		
		Can_EsReg2 = node->ES;	
		if((Can_EsReg2 & BUS_OFF) == BUS_OFF)
		{
			/* BusOff Recovery sequence has started */
			CanBusOffRecoveryStatus[Controller] = TRUE;
		}
	}
	return status;
}

/**********************************************************************************************************************
 * Can_Stop
 *********************************************************************************************************************/
/*! \brief      This function will stop the CAN node.
 *
 *  \param[in]  uint8 Controller -  The controller for which the state change needs to be performed/
 *              CAN_ControllerRegMap *node - Pointer to Register structure.
 *
 *
 *  \context
 *********************************************************************************************************************/
static boolean Can_Stop(uint8 Controller, CAN_ControllerRegMap *node)
{			   
   boolean status = FALSE;
   uint8 loopResult;
   
   if(can_State[Controller]==CAN_STOPPED)
   {
		CanIf_ControllerModeIndication( Controller, CANIF_CS_STOPPED );
		status =  TRUE;
   }
   else
   {
#if (CAN_DEV_ERROR_DETECT == STD_ON)
		if(can_State[Controller]!=CAN_STARTED)
		{
			(void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_SETCTR_ID, (uint8)CAN_E_TRANSITION);
		}
		else
#endif
		{
			/*Set the mode to init mode so that no Can bus activity is there*/
			 node->CTL |= ( ENABLE_INIT_BIT);
			 /*Wait for INIT bit to be set successfully*/
			LoopCounterInitEnd(Controller,(uint8)1U);
			do
			{
				/*SAFETYMCUSW 91D MR:16.10 <APPROVED> "Reason - loopResult is used in while MACRO"*/
				loopResult= LoopCounter(Controller,(uint8)1U);			    
			    /*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/	
				/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - Volatile variable usage is required here since we wait
                  for INIT bit to be set "*/
				/*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason - Volatile variable usage is required here since we wait
                  for INIT bit to be set "*/  
			}while((loopResult!=0U) && (!(((node->CTL) & (ENABLE_INIT_BIT)) == (ENABLE_INIT_BIT)))); 
			LoopCounterInitEnd(Controller,(uint8)1U);
			can_State[Controller] = CAN_STOPPED;
			CanIf_ControllerModeIndication( Controller, CANIF_CS_STOPPED );
			status = TRUE;
			CanBusOffRecoveryStatus[Controller] = FALSE;
		}
   }
   return status;
}			   

/**********************************************************************************************************************
 * Can_Sleep
 *********************************************************************************************************************/
/*! \brief      This function will sleep the CAN node.
 *
 *  \param[in]  uint8 Controller -  The controller for which the state change needs to be performed/
 *              CAN_ControllerRegMap *node - Pointer to Register structure.
 *
 *
 *  \context
 *********************************************************************************************************************/
static boolean Can_Sleep(uint8 Controller, CAN_ControllerRegMap *node)
{               
   boolean status = FALSE;
   uint8 loopResult;
   
   if(can_State[Controller]==CAN_SLEEP)
   {
	  CanIf_ControllerModeIndication( Controller, CANIF_CS_SLEEP );
	  status = TRUE;
   }
   else
   {
#if (CAN_DEV_ERROR_DETECT == STD_ON)
		if(can_State[Controller]!=CAN_STOPPED)
		{
			(void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_SETCTR_ID, (uint8)CAN_E_TRANSITION);
		}
		else
#endif		
		{
			/* Local Power down */
			/*Also enable the status interrupt for wake-up detection*/
			node->CTL |= ( LOCAL_PD_BIT  )|( SIE ); 

			/*Wait for the power down to be successful*/
			LoopCounterInitEnd(Controller,(uint8)1U);
			do
			{
				/*SAFETYMCUSW 91D MR:16.10 <APPROVED> "Reason - loopResult is used in while MACRO"*/
				loopResult= LoopCounter(Controller,(uint8)1U);
				/*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/	
				/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - Volatile variable usage is required here since we wait
                  for power down bit to be set "*/
				/*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason - Volatile variable usage is required here since we wait
                  for power down bit to be set "*/  
			}while((loopResult!=0U) && (!(((node->ES) & (PDA_BIT)) == PDA_BIT))); /*MISRA fixes */
			LoopCounterInitEnd(Controller,(uint8)1U);
			can_State[Controller] = CAN_SLEEP;
			CanIf_ControllerModeIndication( Controller, CANIF_CS_SLEEP );
			status = TRUE;
			CanBusOffRecoveryStatus[Controller] = FALSE;
		}
   }
   return status;
}

/**********************************************************************************************************************
 * Can_WkUp
 *********************************************************************************************************************/
/*! \brief      This function will wakeup CAN node.
 *
 *  \param[in]  uint8 Controller -  The controller for which the state change needs to be performed/
 *              CAN_ControllerRegMap *node - Pointer to Register structure.
 *
 *
 *  \context
 *********************************************************************************************************************/
static boolean Can_WkUp(uint8 Controller, CAN_ControllerRegMap *node)
{
	boolean status = FALSE;
	uint8 loopResult;
	
#if (CAN_DEV_ERROR_DETECT == STD_ON)
	if((can_State[Controller]!=CAN_SLEEP))
	{
		(void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_SETCTR_ID, (uint8)CAN_E_TRANSITION);
	}
	else
#endif
	{		
		/*clear the PDR bit first and then clear the Initbit*/
		node->CTL &= ~((LOCAL_PD_BIT)|( SIE ));/*disable the status interrupt now as we are awake*/
		LoopCounterInitEnd(Controller,(uint8)1U);
		do
		{
			/*SAFETYMCUSW 91D MR:16.10 <APPROVED> "Reason - loopResult is used in while MACRO"*/
			loopResult= LoopCounter(Controller,(uint8)1U);
		    /*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/	
		}
		/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
	    /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
		while((loopResult!=0U) && ((node->ES & PDA_BIT) == PDA_BIT));
		LoopCounterInitEnd(Controller,(uint8)1U);

		/*Dont clear the init bit as we need to be in stopped state it will be clear in start state*/
		can_State[Controller] = CAN_STOPPED;
		CanIf_ControllerModeIndication( Controller, CANIF_CS_STOPPED );
		status = TRUE;
		CanBusOffRecoveryStatus[Controller] = FALSE;
	}
	return status;
}


/**********************************************************************************************************************
 * Can_CheckSetControllerModeDet
 *********************************************************************************************************************/
/*! \brief      This function will check DET for SetControllerMode API.
 *
 *  \param[in]  uint8 Controller Controller Number in the can hardware its 0-3
 *
 *  \context
 *********************************************************************************************************************/
#if (CAN_DEV_ERROR_DETECT == STD_ON)
static boolean Can_CheckSetControllerModeDet(uint8 Controller)
{
	 boolean returnstatus = TRUE;
	/*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   if(Can_ConfigPtr==NULL_PTR)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_SETCTR_ID, (uint8)CAN_E_UNINIT);
	  returnstatus = FALSE;
   }
   else if(Controller >= (Can_ConfigPtr->CanMaxControllerCount))
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_SETCTR_ID, (uint8)CAN_E_PARAM_CONTROLLER);
	  returnstatus = FALSE;
   }
   /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason - FALSE is not part of CAN.This should be fixed outside of CAN."*/
   else if(Can_ConfigPtr->CanControllerList[Controller]->CntrActive == FALSE)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_SETCTR_ID, (uint8)CAN_E_UNINIT);
	  returnstatus = FALSE;
   }
   else
   {
	  /* MISRA C Compliance */
   }
   return returnstatus;
}
#endif


/**********************************************************************************************************************
 * Can_CheckDisableDet
 *********************************************************************************************************************/
/*! \brief      This function will check DET for Enable API.
 *
 *  \param[in]  uint8 Controller Controller Number in the can hardware its 0-3
 *
 *  \context
 *********************************************************************************************************************/
#if (CAN_DEV_ERROR_DETECT == STD_ON)
static boolean Can_CheckDisableDet(uint8 Controller)
{
   boolean returnstatus = TRUE;
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/   
   if (Can_ConfigPtr == NULL_PTR)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_DIINT_ID,(uint8) CAN_E_UNINIT);
	  returnstatus = FALSE;
   }
   else if (Controller >= (Can_ConfigPtr->CanMaxControllerCount))
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_DIINT_ID, (uint8)CAN_E_PARAM_CONTROLLER);
	  returnstatus = FALSE;
   }
   else if(Can_ConfigPtr->CanControllerList[Controller]->CntrActive == FALSE)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_DIINT_ID, (uint8)CAN_E_UNINIT);
	  returnstatus = FALSE;
   }
   else if (can_State[Controller] == CAN_UNINIT)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_DIINT_ID, (uint8)CAN_E_UNINIT);
	  returnstatus = FALSE;
   }
   else
   {
	  /* MISRA C Compliance */
   }   
   return returnstatus;
}
#endif

/**********************************************************************************************************************
 * Can_CheckEnableDet
 *********************************************************************************************************************/
/*! \brief      This function will check DET for Disable API.
 *
 *  \param[in]  uint8 Controller Controller Number in the can hardware its 0-3
 *
 *  \context
 *********************************************************************************************************************/
#if (CAN_DEV_ERROR_DETECT == STD_ON)
static boolean Can_CheckEnableDet(uint8 Controller)
{
   boolean returnstatus = TRUE;
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/   
   if (Can_ConfigPtr == NULL_PTR)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_ENINT_ID,(uint8) CAN_E_UNINIT);
	  returnstatus = FALSE;
   }
   else if (Controller >= (Can_ConfigPtr->CanMaxControllerCount))
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_ENINT_ID, (uint8)CAN_E_PARAM_CONTROLLER);
	  returnstatus = FALSE;
   }
    else if(Can_ConfigPtr->CanControllerList[Controller]->CntrActive == FALSE)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_ENINT_ID, (uint8)CAN_E_UNINIT);
	  returnstatus = FALSE;
   }
   else if (can_State[Controller] == CAN_UNINIT)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_ENINT_ID, (uint8)CAN_E_UNINIT);
	  returnstatus = FALSE;
   }
   else
   {
	  /* MISRA C Compliance */
   }	 
   return returnstatus;
}
#endif


/**********************************************************************************************************************
 * Can_CheckWakeupDet
 *********************************************************************************************************************/
/*! \brief      This function will check DET for Can_CheckWakeup API.
 *
 *  \param[in]  uint8 Controller Controller Number in the can hardware its 0-3
 *
 *  \context
 *********************************************************************************************************************/
#if (CAN_DEV_ERROR_DETECT == STD_ON)
static boolean Can_CheckWakeupDet(uint8 Controller)
{
	boolean returnstatus = TRUE;
	 /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   if (Can_ConfigPtr == NULL_PTR)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0x00U, (uint8)CAN_CKWAKEUP_ID, (uint8)CAN_E_UNINIT);
	  returnstatus = FALSE;
   }
   else if (Controller >= (Can_ConfigPtr->CanMaxControllerCount))
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_CKWAKEUP_ID, (uint8)CAN_E_PARAM_CONTROLLER);
	  returnstatus = FALSE;
   }
   else if (can_State[Controller] == CAN_UNINIT)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_CKWAKEUP_ID, (uint8)CAN_E_UNINIT);
	  returnstatus = FALSE;
   }
   else
   {
	  /* MISRA C Compliance */
   }
   return returnstatus ;
}
#endif /* Can_CheckWakeupDet API */


/**********************************************************************************************************************
 * Can_RxProcess
 *********************************************************************************************************************/
/*! \brief      This function will process all the RX messages and call out the Rx indication
 *
 *  \param[in]  uint16 mailboxID
 *
 *  \context
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_015 */
/* DesignId : CAN_DesignId_025 */
/* Requirements : AR_CAN_SR105, AR_CAN_SR106, AR_CAN_SR107, AR_CAN_SR108 */
/*SAFETYMCUSW 69 S MR:3.4 <APPROVED> "Reason -  Pragma is required here for functions in ISR"*/
#pragma CODE_STATE(Can_RxProcess, 32)
static void Can_RxProcess(uint16 mb) 
{
   uint8 CanController;
   uint32 messageBox ;
   uint32 regIndex ;
   uint32 bitIndex ;
   CAN_ControllerRegMap *node;
   uint8 i;
   uint8 loopResult;
   uint8 Hrh;
   uint8 CanDlc;
   Can_IdType CanId;

   CanController = Can_ConfigPtr->MailBoxList[mb]->Controller->ControllerId;
   /* If the controller is not activated just return */
   if(Can_ConfigPtr->CanControllerList[CanController]->CntrActive == TRUE)   
   {
      /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
	  node = (CAN_ControllerRegMap *)   Can_ConfigPtr->CanControllerList[CanController]->CntrAddr;
      /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
	  if(node != NULL_PTR)      
      {
         messageBox = Can_ConfigPtr->MailBoxList[mb]->HwHandle;
         regIndex = (messageBox - 1U) >> 5U;
         bitIndex = 1U << ((messageBox - 1U) & 0x1FU);

         if((node->NWDATx[regIndex] & bitIndex) == bitIndex) /*Misra fixes*/
         {
            /* Wait until IF2 is ready for use */
            LoopCounterInitEnd(CanController,(uint8)1U);
            do
            {
               /*SAFETYMCUSW 91D MR:16.10 <APPROVED> "Reason - loopResult is used in while MACRO"*/
               loopResult = LoopCounter(CanController,(uint8)1U);
			   /*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/	
			}
			/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
			/*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
			while((loopResult!=0U) && ((node->IF2STAT & BUSY) == BUSY)); /*Misra Fixes*/
            LoopCounterInitEnd(CanController,(uint8)1U);
            node->IF2CMD  = 0x7FU;
			/* Copy MB info into IF2 */
			node->IF2NO = (uint8)messageBox;

#if (CAN_DEV_ERROR_DETECT == STD_ON)
			/* Check if Message is lost/overwritten */
            /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
			if((node->IF2MCTL & 0x00004000U) == 0x00004000U)
			{
			  (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)CanController, \
			                   (uint8)CAN_RXPROCESS_ID, (uint8)CAN_E_DATALOST);
			   /* Clear Message Lost Bit */
			   node->IF2MCTL &= (~CLR_MSG_LOST);
			   node->IF2CMD  = 0x90U ; /* Message Lost bit changed */
			   /* Copy Control into message box */
			   /*SAFETYMCUSW 93S MR:10.3 <APPROVED> "Reason - Casting is done from uint32 to uint8"*/
			   node->IF2NO = (uint8) messageBox ;				   
			}
			else
#endif
			{
				
				/* Wait until data are copied into IF2 */
				LoopCounterInitEnd(CanController,(uint8)1U);
				do
				{
				   /*SAFETYMCUSW 91D MR:16.10 <APPROVED> "Reason - loopResult is used in while MACRO"*/
				   loopResult= LoopCounter(CanController,(uint8)1U);
				   /*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/	
				}
				/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
			    /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
				while((loopResult!=0U) && ((node->IF2STAT & BUSY) == BUSY)); /*Misra Fixes*/
				LoopCounterInitEnd(CanController,(uint8)1U);

				/*Read Can ID*/
				/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
				if(((node->IF2ARB) & (1U<<30U)) == (1U<<30U) ) /*Misra Fixes*/
				{
				   /*since its extended id append it by MSB=1*/
				   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
				   CanId = (Can_IdType)((node->IF2ARB & 0x1FFFFFFFU)|(0x80000000U));
				}
				else
				{
				   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
				   CanId = (node->IF2ARB >> 18U) & 0x7FFU;
				}
				/* Get number of received bytes */
				/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
				CanDlc = (uint8) (node->IF2MCTL & 0x0000000FU);
				/* Read Data field */
				for (i = 0U; i < CanDlc; i++)
				{
				   CanSduPtr[i] = node->IF2DATx.ucData[s_canByteOrder[i]];
				}
				Hrh = (uint8)Can_ConfigPtr->MailBoxList[mb]->CanObjectId;
				/* Call the RX confirmation */
				/*SAFETYMCUSW 93S MR:10.3 <APPROVED> "Reason - CanSduPtr is of type uint8"*/
				CanIf_RxIndication(Hrh, CanId, CanDlc, CanSduPtr);
			}
         }
      }
   }
}


/**********************************************************************************************************************
 * LoopCounter
 *********************************************************************************************************************/
/*! \brief      This is the function for timing the loops. This will increment the loop count and check if it outside
 *              the bounds and then return error or ok based on that.
 *
 *  \param[in]  uint8 controller - 3 controllers are there
 *              uint8 source there are 2 sources IRQ=0 and Application=1
 *
 *  \context
 *********************************************************************************************************************/
/*SAFETYMCUSW 69 S MR:3.4 <APPROVED> "Reason -  Pragma is required here for functions in ISR"*/
#pragma CODE_STATE(LoopCounter, 32)
static FUNC(uint8, CAN_CODE) LoopCounter(uint8 controller, uint8 source) {
	uint8 retval;
	retval = 1U;/*1 - Ok*/
	canLoopTimeout[controller][source]++;
	/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason - This is necessary."*/
	if (canLoopTimeout[controller][source] >= CAN_TIMEOUT_DURATION) {
#if (CAN_DEV_ERROR_DETECT == STD_ON)
		(void)(void)Det_ReportError((uint16) CAN_MODULE_ID, (uint8) controller,
				 canFxnId, (uint8) CAN_E_TIMEOUT_DET);
#endif
		retval = 0U;/* 0 - Not Ok */
		/* we can use this for indicating some cancellation and failure */
	}
	return retval;
}


/**********************************************************************************************************************
 *  API DEFINITIONS
 *********************************************************************************************************************/
 
/**********************************************************************************************************************
 * Can_Init
 *********************************************************************************************************************/
/*! \brief     This function initilises the CAN controller 
 *
 *              All the required initilisation for the CAN driver and hardware is performed in this function.
 *
 *  \param[in]  Can_ConfigPtr  Pointer to post-build configuration data.
 *
 *  \context    App
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_001 */
/* DesignId : CAN_DesignId_007 */
/* Requirements : AR_CAN_SR116, AR_CAN_SR117, AR_CAN_SR118, AR_CAN_SR119, AR_CAN_SR125, AR_CAN_SR126, AR_CAN_SR142,
                  AR_CAN_SR143, AR_CAN_SR144, AR_CAN_SR145, AR_CAN_SR4, AR_CAN_SR39, AR_CAN_SR40, AR_CAN_SR43,
                  AR_CAN_SR76, AR_CAN_SR123*/
FUNC(void, CAN_CODE) Can_Init(P2CONST( Can_ConfigType, AUTOMATIC, CAN_PBCFG) ConfigPtr )
{
   uint8 controller_cntr;
   uint8 controller_max;

#if (CAN_DEV_ERROR_DETECT == STD_ON)
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   if (NULL_PTR == ConfigPtr)
   {
      /* Can config pointer is NOT valid */
		(void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0U, (uint8)CAN_INIT_ID, (uint8)CAN_E_PARAM_POINTER);
   }   
   else
#endif
	{
		Can_ConfigPtr = ConfigPtr;

		for(controller_max=0U; controller_max<KMAX_CONTROLLER;controller_max++)
		{
			canBaud[controller_max] = 0U;
		}

		for(controller_cntr=0U;controller_cntr<Can_ConfigPtr->CanMaxControllerCount;controller_cntr++)
		{
#if (CAN_DEV_ERROR_DETECT == STD_ON)
			if(can_State[controller_cntr]!=CAN_UNINIT)
			{
				/* Can controller is in not in UNINT state */
				(void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0U, (uint8)CAN_INIT_ID, (uint8)CAN_E_TRANSITION);
			}
			else
#endif
			{
				/*If Controller is active then only do initialization */
				/*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason - TRUE is not part of CAN.This should be
				 fixed outside of CAN."*/
				if(Can_ConfigPtr->CanControllerList[controller_cntr]->CntrActive == TRUE)
				{
					/* Init individual controller (may be moved to SetControllerMode(start state)) */
					ConfigController(controller_cntr);
					/* initialize the interrupt counter to zero */
					canInterruptCounter[controller_cntr] = 0U;
					/* change the state to stopped from the UNINIT state */
					can_State[controller_cntr]= CAN_STOPPED;
					/* Update BusOff Recovery status */
					CanBusOffRecoveryStatus[controller_cntr] = FALSE;
				}
			}
		}
	}
}
#if (CAN_VERSION_INFO_API == STD_ON)
/**********************************************************************************************************************
 * Can_GetVersionInfo
 *********************************************************************************************************************/
/*! \brief      This function will return the version for this module
 *
 *  \param[in]  None
 *
 *  \param[out]    Std_VersionInfoType VersionInfo - the structure that will contain version info after fxn call.
 *
 *  \context    App
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_022 */
/* DesignId : CAN_DesignId_008 */
/* Requirements : AR_CAN_SR116, AR_CAN_SR146, AR_CAN_SR147, AR_CAN_SR148, AR_CAN_SR149, AR_CAN_SR150 */
FUNC(void, CAN_CODE)  Can_GetVersionInfo(P2VAR(Std_VersionInfoType, AUTOMATIC, CAN_APPL_DATA) VersionInfo )
{
#if (CAN_DEV_ERROR_DETECT == STD_ON)
	canFxnId = CAN_VERSION_ID;
	/*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
	if (VersionInfo == NULL_PTR)
	{
		(void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0U, (uint8)CAN_VERSION_ID, (uint8)CAN_E_PARAM_POINTER);
	}
	else
#endif
	{
		VersionInfo->vendorID = (uint16)CAN_VENDOR_ID;
		VersionInfo->moduleID = (uint16)CAN_MODULE_ID;
		VersionInfo->sw_major_version = (uint8)CAN_SW_MAJOR_VERSION;
		VersionInfo->sw_minor_version = (uint8)CAN_SW_MINOR_VERSION;
		VersionInfo->sw_patch_version = (uint8)CAN_SW_PATCH_VERSION;
	}
}
#endif
/**********************************************************************************************************************
 * Can_Write
 *********************************************************************************************************************/
/*! \brief      This function will write the data into Can mail boxes.
 *
 *  \param[in]  uint8 Hth -  This is the Msg box number its a unique number.
 *              Can_PduInfoPtrType PduInfo - the CAN message to be transmitted.
 *
 *
 *  \context    App
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_002 */
/* DesignId : CAN_DesignId_015 */
/* Requirements : AR_CAN_SR85, AR_CAN_SR86, AR_CAN_SR88, AR_CAN_SR104, AR_CAN_SR116, AR_CAN_SR120, AR_CAN_SR190,
                  AR_CAN_SR191, AR_CAN_SR192, AR_CAN_SR195, AR_CAN_SR196, AR_CAN_SR197, AR_CAN_SR198,
                  AR_CAN_SR200, AR_CAN_SR8*/
FUNC(Can_ReturnType, CAN_CODE) Can_Write( uint8 Hth, Can_PduInfoPtrType PduInfo )
{
	uint32 i;
	Can_ReturnType status = CAN_OK;
	uint32 messageBox;
	uint32 regIndex;
	uint32 bitIndex;
	CAN_ControllerRegMap* node;
	/*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
	uint8* deref_data = NULL_PTR;
	uint8 MsgCntrlr;
	uint8 loopResult;
	uint16 Hth1;

#if (CAN_DEV_ERROR_DETECT == STD_ON)
	canFxnId = CAN_WRITE_ID;
	/*SAFETYMCUSW 96 S MR:6.2,10.1,10.2,12.6 <APPROVED> "Reason - TRUE and FALSE is not part of CAN."*/
   if(FALSE == Can_CheckWriteDet(Hth,PduInfo))
   {
	  status = CAN_NOT_OK;
   }   
   else
#endif
   {
      Hth1=CanHtrhMbMapping[Hth];
      MsgCntrlr = Can_ConfigPtr->MailBoxList[Hth1]->Controller->ControllerId;
#if (CAN_DEV_ERROR_DETECT == STD_ON)
      /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason - FALSE is not part of CAN.This should be fixed outside of CAN."*/
	  if(Can_ConfigPtr->CanControllerList[MsgCntrlr]->CntrActive  == FALSE)
      {
         /* Can controller is not valid */
        (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0U, (uint8)CAN_WRITE_ID, (uint8)CAN_E_UNINIT);
         status = CAN_NOT_OK;
      }
      else
#endif
      {         
		 /* CanSM has triggered a new write after L1 timeout. Stop the BusOff recovery.
		    CanSM will trigger a new bus off recovery sequence. */
		 CanBusOffRecoveryStatus[MsgCntrlr] = FALSE;
		 /* Misra fixes */
         /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
		 /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/	
		 if ( NULL_PTR == (void *)Can_ConfigPtr->MailBoxList[Hth1]->Controller->CntrAddr )
         {
            status = CAN_NOT_OK ;
         }
         else
         {
            Can_EnterCritical();
			
			/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - CntrAddr is checked for NULL_PTR before assigning "*/
            /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
			node = (CAN_ControllerRegMap *)  Can_ConfigPtr->MailBoxList[Hth1]->Controller->CntrAddr;

            messageBox = (Can_ConfigPtr->MailBoxList[Hth1]->HwHandle);
            regIndex = (messageBox - 1U) >> 5U;
            bitIndex = 1U << ((messageBox - 1U) & 0x1FU);

            /* 	  - Check for pending message:
            *     - pending message, return 0
            *     - no pending message, start new transmission
            */

            if ((node->TXRQx[regIndex] & bitIndex) == bitIndex)
            {
               status =  CAN_BUSY;
            }
            else if (canTxRxStatus[Hth1] == 1U) /*Previous transmission is not yet acked*/
            {
               status =  CAN_BUSY;
            }
            else
            {
               /*  Wait until IF1 is ready for use */
               /*SAFETYMCUSW 9S MR:12.2 <APPROVED> "Reason - To assign canlooptimeout to 0 "*/
               LoopCounterInitEnd(MsgCntrlr,(uint8)1U);
               do
               {
                  loopResult= LoopCounter(MsgCntrlr,(uint8)1U);
                  /*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/	
			   }
			   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
			   /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
			   while((loopResult!=0U) && ((node->IF1STAT & BUSY) == BUSY)); /*Fix Misra C violations */
               /*SAFETYMCUSW 9S MR:12.2 <APPROVED> "Reason - To assign canlooptimeout to 0 "*/
               LoopCounterInitEnd(MsgCntrlr,(uint8)1U);
               /* MISRA Fix */
               /* if loop exit was due to time out exit from this function */
               if(loopResult == 0U )
               {
                  status = CAN_NOT_OK ;
               }
               else
               {
                 /* Copy TX data into IF1 */		
				 deref_data = PduInfo->sdu;
				 for (i = 0U; i < PduInfo->length; i++)
				 {					
					/*SAFETYMCUSW 436 S MR:17.1, 17.4 <APPROVED> "Reason - deref_data cannot be declared as 
					 array as software does not know the length of the data at compile time */
					/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason -  PduInfo->sdu is already checked for NULLPTR."*/
					node->IF1DATx.ucData[s_canByteOrder[i]] = deref_data[i];					
				 }

				 node->IF1ARB = (( MSG_VAL_BIT ) | ((Can_ConfigPtr->MailBoxList[Hth1]->MBIdType ) << (30U))
							  | (( Can_ConfigPtr->MailBoxList[Hth1]->MBDir ) << (29U) ));
				 /*Set the ID according to the MB Type from the Hth1 */
				 Can_SetId(Hth1, node, PduInfo);
				 /*Store the transmitted Pdu SWPdu Handle for Tx confirmation*/
				 canTxRxPduId[Hth1] = PduInfo->swPduHandle;

				 node->IF1MCTL = CTL_PATTERN | PduInfo->length ; /*Copy the exact length to be transmitted*/
				 /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason - TRUE is not part of CAN.This should be fixed 
				   outside of CAN."*/
				 if( Can_ConfigPtr->CanControllerList[MsgCntrlr]->TxInterrupt == TRUE )
				 {
					node->IF1MCTL |= ENABL_TX_INTERRUPT;
				 }

				 node->IF1CMD  = 0xB7U ; /* ID's changed, length is changed*/

				 /* Copy TX data into message box */
				 /*SAFETYMCUSW 93S MR:10.3 <APPROVED> "Reason - Casting is done from uint32 to uint8"*/
				 node->IF1NO = (uint8) messageBox ;

				 /* set that this object is transmitted.*/
				 canTxRxStatus[Hth1] = 1U;                  
               }
            }
          Can_LeaveCritical();
		 }		 
      }
   }
   return status;
}

/**********************************************************************************************************************
 * Can_ConfigBaudRate
 *********************************************************************************************************************/
/*! \brief      This function will configure the baud rate.
 *
 *  \param[in]  uint8 Controller -  The controller for which the state change needs to be performed/
 *              CAN_ControllerRegMap *node - Pointer to register structure.
 *
 *
 *  \context
 *********************************************************************************************************************/
static void Can_ConfigBaudRate(uint8 Controller,CAN_ControllerRegMap *node)
{
	uint16 brp;   
	uint8 tSeg1;
	uint8 tSeg2;
	
	/*SAFETYMCUSW 93 S MR:10.3 <APPROVED> "Reason - To check for baud rate change"*/
	if((canBaud[Controller] & 0x3FFU) != 0x000U)
    {
		brp=(canBaud[Controller] & 0x3FFU);
	}
	else
	{
		brp = Can_ConfigPtr->CanControllerList[Controller]->DefaultBaud->BrpValue;
	}
	brp = brp-1U;

	/* Setup bit timing */
	tSeg1=(Can_ConfigPtr->CanControllerList[Controller]->DefaultBaud->Pseg1+
	       Can_ConfigPtr->CanControllerList[Controller]->DefaultBaud->PropSeg);
	tSeg2=Can_ConfigPtr->CanControllerList[Controller]->DefaultBaud->Pseg2;
      
	node->BTR = (((brp & 0x3C0U)>>0x06U) << 16U) |
            	((((tSeg2-1U)&0x7U)<< 12U ) |(((tSeg1-1U)& 0x0FU) << 8U)) |
                (((Can_ConfigPtr->CanControllerList[Controller]->DefaultBaud->Sjw-1U)  & 0x03U)<< 6U) | 
                (((Can_ConfigPtr->CanControllerList[Controller]->DefaultBaud->Sjw-1U)  & 0x03U)<< 6U) | 
				((brp) &0x3FU);
	
}

/**********************************************************************************************************************
 * Can_SetControllerMode
 *********************************************************************************************************************/
/*! \brief      This function will transition the controller to different states, Its autosar defined states.
 *
 *  \param[in]  uint8 Controller -  The controller for which the state change needs to be performed/
 *              Can_StateTransitionType Transition - the state to which controller needs to move in.
 *
 *
 *  \context
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_024 */
/* DesignId : CAN_DesignId_011 */
/* Requirements : AR_CAN_SR42, AR_CAN_SR164, AR_CAN_SR165, AR_CAN_SR166, AR_CAN_SR172, AR_CAN_SR173, AR_CAN_SR174,
                  AR_CAN_SR52, AR_CAN_SR54, AR_CAN_SR55, AR_CAN_SR58, AR_CAN_SR59, AR_CAN_SR60, AR_CAN_SR64,
                  AR_CAN_SR67 */
FUNC(Can_ReturnType, CAN_CODE) Can_SetControllerMode( uint8 Controller, Can_StateTransitionType Transition )
{
   CAN_ControllerRegMap *node;
   Can_ReturnType status = CAN_NOT_OK;   

   /*check for the validity of the controller parameter if det is enabled*/
#if (CAN_DEV_ERROR_DETECT == STD_ON)
   canFxnId = CAN_SETCTR_ID;
   /*SAFETYMCUSW 96 S MR:6.2,10.1,10.2,12.6 <APPROVED> "TRUE,FALSE comes from compiler. It should be solved there."*/
   if(FALSE == Can_CheckSetControllerModeDet(Controller))
   {
		/* Det Error is already reported */
   }
   else   
#endif
   {
      /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
	  node =(CAN_ControllerRegMap *)  Can_ConfigPtr->CanControllerList[Controller]->CntrAddr;
      /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
	  if(node != NULL_PTR)      
      {
         switch(Transition)
         {
            case CAN_T_START:
			{	
				/*SAFETYMCUSW 96 S MR:6.2,10.1,10.2,12.6 <APPROVED> "TRUE,FALSE comes from compiler." */
				if(TRUE == Can_Start(Controller, node))
				{
					status =  CAN_OK;
				}
				break;	
			}	
            case CAN_T_STOP:
            {
            	/*SAFETYMCUSW 96 S MR:6.2,10.1,10.2,12.6 <APPROVED> "TRUE,FALSE comes from compiler." */
               if(TRUE == Can_Stop(Controller, node))
				{
					status =  CAN_OK;
				}
				break;
            }

            case CAN_T_SLEEP :
            {	   
            	/*SAFETYMCUSW 96 S MR:6.2,10.1,10.2,12.6 <APPROVED> "TRUE,FALSE comes from compiler." */
			   if(TRUE == Can_Sleep(Controller, node))
				{
					status =  CAN_OK;
				}
				break;
            }
            case CAN_T_WAKEUP :
            {
            	/*SAFETYMCUSW 96 S MR:6.2,10.1,10.2,12.6 <APPROVED> "TRUE,FALSE comes from compiler." */
				if(TRUE == Can_WkUp(Controller, node))
				{
					status =  CAN_OK;
				}
				break;
            }
            default: 
            {
               status = CAN_NOT_OK; /* To fix Misra C violations */
               break;
            }
         }
      }/*End of else if(node == NULL_PTR)*/
   }
   return status;
}

/**********************************************************************************************************************
 * Can_DisableControllerInterrupts
 *********************************************************************************************************************/
/*! \brief      This function will Disable the interrupts for the Controller desired.
 *              Basically it will Disable the CAN interrupts(reset bit 1 in CTL reg(IE0=0)).
 *
 *  \param[in]  uint8 Controller Controller Number in the can hardware its 0-3
 *
 *  \context
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_025 */
/* DesignId : CAN_DesignId_012 */
/* Requirements : AR_CAN_SR175, AR_CAN_SR176, AR_CAN_SR177, AR_CAN_SR178, AR_CAN_SR179, AR_CAN_SR180 */
FUNC(void, CAN_CODE)  Can_DisableControllerInterrupts( uint8 Controller )
{
   uint8 InterruptCounter;
#if (CAN_DEV_ERROR_DETECT == STD_ON)
   canFxnId = CAN_DIINT_ID;
   /*SAFETYMCUSW 96 S MR:6.2,10.1,10.2,12.6 <APPROVED> "TRUE,FALSE comes from compiler." */
   if(FALSE == Can_CheckDisableDet(Controller))
   {
		/* Det Error is already reported */
   }
   else
#endif
   {
      Can_EnterCritical();
      InterruptCounter = canInterruptCounter[Controller];      
#if (CAN_DEV_ERROR_DETECT == STD_ON)
      /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason - FALSE is not part of CAN.This should be fixed outside of CAN."*/
	  if((Can_ConfigPtr->CanControllerList[Controller]->RxInterrupt == FALSE) 
         /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason - FALSE is not part of CAN.This should be fixed 
		   outside of CAN."*/
		 && (Can_ConfigPtr->CanControllerList[Controller]->TxInterrupt == FALSE) )
        {
           (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, \
			                (uint8)CAN_DIINT_ID, (uint8)CAN_E_PARAM_CONTROLLER);
        }  
        else
#endif
        {
           CAN_ControllerRegMap *node;
           /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
		   node = (CAN_ControllerRegMap *)   Can_ConfigPtr->CanControllerList[Controller]->CntrAddr;
           /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
		   if(node != NULL_PTR)           
           {
              node->CTL &= ~(Can_ConfigPtr->CanControllerList[Controller]->InterrupMask);              
              canInterruptCounter[Controller] = InterruptCounter + 1U;
              Can_LeaveCritical();
           }/*End of else*/
        }      
   }
}
/**********************************************************************************************************************
 * Can_EnableControllerInterrupts
 *********************************************************************************************************************/
/*! \brief      This function will Enable the interrupts for the Controller desired. It will restore the interrupts
 *              that were defined in the configuration. Basically it will enable the CAN interrupts.
 *
 *  \param[in]  uint8 Controller Controller Number in the can hardware its 0-3
 *
 *  \context
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_026 */
/* DesignId : CAN_DesignId_013 */
/* Requirements : AR_CAN_SR181, AR_CAN_SR182, AR_CAN_SR183, AR_CAN_SR184, AR_CAN_SR185 */
FUNC(void, CAN_CODE)  Can_EnableControllerInterrupts( uint8 Controller )
{
   uint8 InterruptCounter;
#if (CAN_DEV_ERROR_DETECT == STD_ON)
   canFxnId = CAN_ENINT_ID;
   /*SAFETYMCUSW 96 S MR:6.2,10.1,10.2,12.6 <APPROVED> "TRUE,FALSE comes from compiler." */
   if(FALSE == Can_CheckEnableDet(Controller))
   {
		/* Det Error is already reported */
   }
   else   
#endif
   {
      Can_EnterCritical();
      InterruptCounter = canInterruptCounter[Controller];
      if (InterruptCounter != 0U)
      {         
        canInterruptCounter[Controller] = InterruptCounter - 1U;
        InterruptCounter = canInterruptCounter[Controller];
        if (InterruptCounter == 0U)
        {
           CAN_ControllerRegMap *node;
           /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
		   node = (CAN_ControllerRegMap *)   Can_ConfigPtr->CanControllerList[Controller]->CntrAddr;
           /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
		   if(node != NULL_PTR)           
           {
              node->CTL |= Can_ConfigPtr->CanControllerList[Controller]->InterrupMask;
           }/*End of Else*/
        }/*End of if (InterruptCounter == 0U)*/
      }/*End of if (InterruptCounter != 0U)*/
      Can_LeaveCritical();
   }
}

/**********************************************************************************************************************
 * Can_MainFunction_Write
 *********************************************************************************************************************/
/*! \brief      This function performs the polling of TX confirmation and TX cancellation confirmation
 *              when CAN_TX_PROCESSING is set to POLLING.
 *
 *  \param[in]  void
 *
 *  \context
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_028 */
/* DesignId : CAN_DesignId_016 */
/* Requirements : AR_CAN_SR88, AR_CAN_SR206, AR_CAN_SR208, AR_CAN_SR209, AR_CAN_SR210, AR_CAN_SR211 */
FUNC(void, CAN_CODE)  Can_MainFunction_Write( void )
{
#if  (CAN_TX_POLLING == STD_ON)
   uint8 htrh;
   uint8 Controller2;
   uint32 messageBox ;
   uint32 regIndex ;
   uint32 bitIndex ;
   CAN_ControllerRegMap *node;

#if (CAN_DEV_ERROR_DETECT == STD_ON)
   canFxnId = CAN_MAINFCT_WRITE_ID;
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   if (Can_ConfigPtr == NULL_PTR)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0x00U,(uint8) CAN_MAINFCT_WRITE_ID, (uint8)CAN_E_UNINIT);
   }
   else
#endif
   {
      for(htrh=0U;htrh < Can_ConfigPtr->MaxMbCnt;htrh++ )
      {
         /* only for the Tx Mailbox */
         if(Can_ConfigPtr->MailBoxList[htrh]->MBDir == 1U)
         {
            Controller2 = Can_ConfigPtr->MailBoxList[htrh]->Controller->ControllerId;
            /* If the controller is not active then skip rest of processing */
            if(Can_ConfigPtr->CanControllerList[Controller2]->CntrActive == TRUE)            
			{
				/*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
				node = (CAN_ControllerRegMap *)   Can_ConfigPtr->CanControllerList[Controller2]->CntrAddr;
				/*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
				if(node != NULL_PTR)				
				{
				   messageBox = Can_ConfigPtr->MailBoxList[htrh]->HwHandle;
				   regIndex = (messageBox - 1U) >> 5U;
				   bitIndex = 1U << ((messageBox - 1U) & 0x1FU);

				   if((canTxRxStatus[htrh] == 1U) && !((node->TXRQx[regIndex] & bitIndex) == bitIndex))
				   {
					  /* Clear the status as data is already sent */
					  canTxRxStatus[htrh] = 0U;
					  /* Call TX confirmation */
					  CanIf_TxConfirmation(canTxRxPduId[htrh]);
				   }
				}
			}
         }
      }
   }
#endif /*  */
}
/**********************************************************************************************************************
 * Can_CheckWakeup
 *********************************************************************************************************************/
/*! \brief      This function will check the wakeup status for that controller.
 *
 *  \param[in]  uint8 Controller -  The controller for which the wake status need to be checked
 *
 *  \return      Can_ReturnType  CAN_OK      - if wakeup is detected.
 *                               CAN_NOT_OK  - if Wakeup is not detected
 *
 *  \context
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_027 */
/* DesignId : CAN_DesignId_014 */
/* Requirements : AR_CAN_SR186, AR_CAN_SR187, AR_CAN_SR188, AR_CAN_SR189  */
FUNC(Can_ReturnType, CAN_CODE) Can_CheckWakeup( uint8 Controller )
{
   CAN_ControllerRegMap *node;
   uint32 Reg_ES;
   uint32 Reg_CTL;
   Can_ReturnType status = CAN_NOT_OK ;

#if (CAN_DEV_ERROR_DETECT == STD_ON)
   canFxnId = CAN_CKWAKEUP_ID;
   /*SAFETYMCUSW 96 S MR:6.2,10.1,10.2,12.6 <APPROVED> "TRUE,FALSE comes from compiler." */
   if(FALSE == Can_CheckWakeupDet(Controller))
   {
		/* Det Error is already reported */
   }   
   else
#endif
   {
      /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
	  node = (CAN_ControllerRegMap *)   Can_ConfigPtr->CanControllerList[Controller]->CntrAddr;
      /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
	  if(node != NULL_PTR)      
      {
         Reg_ES = node->ES;
         Reg_CTL = node->CTL;
         if(((Reg_ES & PDA_BIT) == PDA_BIT) && ((Reg_CTL & (LOCAL_PD_BIT)) == (LOCAL_PD_BIT)) &&
            ((Reg_CTL & (1U<<0U)) == (1U<<0U)) )
         {
            /*Sleeping*/
            status = CAN_NOT_OK;
         }
         else
         {
            /* Wakeup*/
            status = CAN_OK;
         }
      }/*End of else*/
   }
   return status;
}

#if (CAN_CHANGE_BAUDRATE_API == STD_ON)
/**********************************************************************************************************************
 * Can_CheckBaudrate
 *********************************************************************************************************************/
/*! \brief      This service shall check, if a certain CAN controller supports a requested baudrate
 *
 *  \param[in]  uint8 Controller -  The controller for which the Baud is to be checked
 *              const uint16 Baudrate - Baudrate in KB
 *
 *  \return        Std_ReturnType -  E_OK      - Baud supported by Can Controller.
 *                                   E_NOT_OK  - Baud is not supported by Can Controller
 *
 *  \context
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_023 */
/* DesignId : CAN_DesignId_009*/
/* Requirements : AR_CAN_SR151, AR_CAN_SR153, AR_CAN_SR154, AR_CAN_SR155, AR_CAN_SR156, AR_CAN_SR157 */
FUNC(Std_ReturnType, CAN_CODE) Can_CheckBaudrate( uint8 Controller, const uint16 Baudrate )
{
   uint16 brp;
   uint16 temp;   
   /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason - Std_ReturnType is not part of CAN.This should be 
   fixed outside of CAN."*/
   Std_ReturnType status =  E_NOT_OK;
#if (CAN_DEV_ERROR_DETECT == STD_ON)
   canFxnId = CAN_CHKBAUDRATE_ID;
   /*SAFETYMCUSW 96 S MR:6.2,10.1,10.2,12.6 <APPROVED> "TRUE,FALSE comes from compiler." */
   if(FALSE == Can_CheckBaudrateDet(Controller))
   {
		/* Det Error is already reported */
   }   
   else
#endif
   {
      /* Validate the baud rate by calculating the BRPE */
      /* brp is brp*10 needed for rounding*/
      brp = ((10000U*(CLK_AV_FREQ))
        /(Baudrate *(1U+ Can_ConfigPtr->CanControllerList[Controller]->DefaultBaud->TimingValues)));
      /*Rounding the BRP value to nearest Integer */
      temp = brp % 10U;
      if(temp>=5U)
      {
         brp=(brp/10U)+1U;
      }
      else
      {
         brp=(brp/10U);
      }

      if (brp > 0x3FFU)
      {
#if (CAN_DEV_ERROR_DETECT == STD_ON)
        (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0x00U, (uint8)CAN_ENINT_ID, (uint8)CAN_E_PARAM_BAUDRATE);
#endif      
      }
      else
      {
         /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason - Std_ReturnType is not part of CAN.This should be 
		   fixed outside of CAN."*/
		 status = E_OK;
      }
   }
   return status;
}

/**********************************************************************************************************************
 * Can_CheckBaudrateDet
 *********************************************************************************************************************/
/*! \brief      This function will check DET for Can_CheckBaudrate API.
 *
 *  \param[in]  uint8 Controller Controller Number in the can hardware its 0-3
 *
 *  \context
 *********************************************************************************************************************/
#if (CAN_DEV_ERROR_DETECT == STD_ON)
static boolean Can_CheckBaudrateDet(uint8 Controller)
{
	boolean returnstatus = TRUE;
	/*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   if (Can_ConfigPtr == NULL_PTR)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0x00U, (uint8)CAN_CHKBAUDRATE_ID, (uint8)CAN_E_UNINIT);
	  returnstatus = FALSE;
   }
   else if (Controller >= (Can_ConfigPtr->CanMaxControllerCount))
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, \
	                  (uint8)CAN_CHKBAUDRATE_ID, (uint8)CAN_E_PARAM_CONTROLLER);
	  returnstatus = FALSE;
   }
   else if ((can_State[Controller] != CAN_STOPPED))
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_CHKBAUDRATE_ID, (uint8)CAN_E_TRANSITION);
	  returnstatus = FALSE;
   }
   else
   {
	  /* MISRA C Compliance */
   }
   return returnstatus ;
}
#endif /* Can_CheckBaudrateDet API */

/**********************************************************************************************************************
 * Can_ChangeBaudrate
 *********************************************************************************************************************/
/*! \brief      This service shall change the baudrate of the CAN controller.
 *
 *  \param[in]  uint8 Controller -  The controller for which the Baud is to be changed
 *              const uint16 Baudrate - Baudrate in KB
 *
 *  \return        Std_ReturnType -  E_OK      - Baud accepted and change applied
 *                                   E_NOT_OK  - Baud is not accepted by controller and no change done.
 *
 *  \context
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_007 */
/* DesignId : CAN_DesignId_010 */
/* Requirements : AR_CAN_SR81, AR_CAN_SR158, AR_CAN_SR159, AR_CAN_SR160, AR_CAN_SR161, AR_CAN_SR162,
                  AR_CAN_SR44, AR_CAN_SR45, AR_CAN_SR46, AR_CAN_SR82 */
FUNC(Std_ReturnType, CAN_CODE) Can_ChangeBaudrate( uint8 Controller, const uint16 Baudrate )
{
   CAN_ControllerRegMap *node;
   uint16 brp;
   uint16 temp;
   /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason - Std_ReturnType is not part of CAN.This should be
     fixed outside of CAN."*/
   Std_ReturnType status = E_NOT_OK;

#if (CAN_DEV_ERROR_DETECT == STD_ON)
   canFxnId = CAN_CHNGBAUDRATE_ID;
   /*SAFETYMCUSW 96 S MR:6.2,10.1,10.2,12.6 <APPROVED> "TRUE,FALSE comes from compiler." */
   if(FALSE == Can_ChangeBaudrateDet(Controller))
   {
		/* Det Error is already reported */
   }
   else   
#endif
   {
      /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
	  node = (CAN_ControllerRegMap *)   Can_ConfigPtr->CanControllerList[Controller]->CntrAddr;
      /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
	  if(node != NULL_PTR)
      {
         /*Perform the can controller initilisation*/
         ConfigController(Controller);

         /* Validate the baud rate by calculating the BRPE */
         /* brp is brp*10 needed for rounding */
         brp =((10000U*(CLK_AV_FREQ))
           /(Baudrate * (1U+Can_ConfigPtr->CanControllerList[Controller]->DefaultBaud->TimingValues)));
         /*Rounding the BRP value to nearest Integer */
         temp = brp % 10U;
         if(temp>=5U)
         {
            brp=(brp/10U)+1U;
         }
         else
         {
            brp=(brp/10U);
         }

         /* brp=brp-1 as we need to write one less into the register*/
         brp= brp-1U;
         /*Validate brp to be less than 10bit*/
         if (brp > 0x3FFU)
         {
#if (CAN_DEV_ERROR_DETECT == STD_ON)
           (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0x00U, \
			                (uint8)CAN_CHNGBAUDRATE_ID, (uint8)CAN_E_PARAM_BAUDRATE);
#endif
         }
         else
         {
            /* Set the Config Change Enable*/
            node->CTL |= (1U<< 6U);
            /* Clear the BRP in BTR reg*/
            node->BTR &=~0xF003FU;

            /* Set the BRP to the new value*/
            node->BTR |= (brp) & 0x3FU; /* LSB*/
            node->BTR |= (((brp & 0x3C0U)>>0x06U) << 16U); /* MSB */

            /* reset the Config Change Enable*/
            node->CTL &= ~(1U<< 6U);
            canBaud[Controller] = brp; /* Store the valid BRP for next time */
            /*SAFETYMCUSW 331 S MR:10.1 <APPROVED> "Reason - Std_ReturnType is not part of CAN.This should be fixed 
			  outside of CAN."*/
			status = E_OK;
         }
      }
   }
   return status;
}

/**********************************************************************************************************************
 * Can_ChangeBaudrateDet
 *********************************************************************************************************************/
/*! \brief      This function will check DET for Can_ChangeBaudrate API.
 *
 *  \param[in]  uint8 Controller Controller Number in the can hardware its 0-3
 *
 *  \context
 *********************************************************************************************************************/
#if (CAN_DEV_ERROR_DETECT == STD_ON)
static boolean Can_ChangeBaudrateDet(uint8 Controller)
{
	boolean returnstatus = TRUE;
	/*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   if (Can_ConfigPtr == NULL_PTR)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0x00U, (uint8)CAN_CHNGBAUDRATE_ID, (uint8)CAN_E_UNINIT);
	  returnstatus = FALSE;
   }
   else if (Controller >= (Can_ConfigPtr->CanMaxControllerCount))
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, \
	                  (uint8)CAN_CHNGBAUDRATE_ID, (uint8)CAN_E_PARAM_CONTROLLER);
	  returnstatus = FALSE;
   }
   else if ((can_State[Controller] != CAN_STOPPED))
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller, (uint8)CAN_CHNGBAUDRATE_ID, (uint8)CAN_E_TRANSITION);
	  returnstatus = FALSE;
   }
   else
   {
	  /* MISRA C Compliance */
   }
   return returnstatus ;
}
#endif /* Can_ChangeBaudrateDet API */

#endif /* CAN_CHANGE_BAUDRATE_API */

/**********************************************************************************************************************
 * Can_MainFunction_Wakeup
 *********************************************************************************************************************/
/*! \brief      This function performs the polling of wake-up events that are configured statically as 'to be polled'.
 *
 *  \param[in]  void
 *
 *  \context
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_029 */
/* DesignId : CAN_DesignId_019 */
/* Requirements : AR_CAN_SR222, AR_CAN_SR223, AR_CAN_SR224, AR_CAN_SR225 */
FUNC(void, CAN_CODE)  Can_MainFunction_Wakeup( void )
{
#if  (CAN_WAKEUP_POLLING == STD_ON)
   uint8 controller_cntr;
   CAN_ControllerRegMap *node;
   uint32 Can_CtlReg1;
   uint32 Can_EsReg1;
   

#if (CAN_DEV_ERROR_DETECT == STD_ON)
   canFxnId = CAN_MAINFCT_WU_ID;
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   if (Can_ConfigPtr == NULL_PTR)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0x00U, (uint8)CAN_MAINFCT_WU_ID, (uint8)CAN_E_UNINIT);
   }
   else
#endif
   {
      for(controller_cntr=0U;controller_cntr<Can_ConfigPtr->CanMaxControllerCount;controller_cntr++)
      {
         /* If the controller is not activated just skip its checking */
         if(Can_ConfigPtr->CanControllerList[controller_cntr]->CntrActive == TRUE)         
		 {
			 /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
			 node = (CAN_ControllerRegMap *)   Can_ConfigPtr->CanControllerList[controller_cntr]->CntrAddr;
			 /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
			 if(node != NULL_PTR)			 
			 {
				Can_CtlReg1 = node->CTL;
				Can_EsReg1 = node->ES;
				if((((Can_EsReg1 & PDA_BIT)) == (PDA_BIT))&&
				   ((Can_CtlReg1 & (LOCAL_PD_BIT)) == (LOCAL_PD_BIT)) && 
				   ((Can_CtlReg1 & (1U<<0U)) == (1U<<0U)))
				{
				   /*  Still Sleeping so indicate sleep */
				   /* CanIf_ControllerModeIndication( controller_cntr,  CANIF_CS_SLEEP )*/
				}
				else
				{
				   /* Call the Wakeup indication function */
				   /*CanIf_ControllerModeIndication( controller_cntr, CANIF_CS_STOPPED  )*/
				   if(CAN_SLEEP == can_State[controller_cntr])
				   {
					   if(controller_cntr == 0U)
					   {
#ifdef WAKEUP_SOURCE_REF_0
						  EcuM_CheckWakeup((EcuM_WakeupSourceType)WAKEUP_SOURCE_REF_0); /* check */
#endif
					   }
					   else if(controller_cntr == 1U)
					   {
#ifdef WAKEUP_SOURCE_REF_1
						  EcuM_CheckWakeup((EcuM_WakeupSourceType)WAKEUP_SOURCE_REF_1); /* check */
#endif
					   }
					   else
					   {
						  /* This else will be empty when WAKEUP_SOURCE_REF_2 is disabled */
#ifdef WAKEUP_SOURCE_REF_2
						  EcuM_CheckWakeup((EcuM_WakeupSourceType)WAKEUP_SOURCE_REF_2); /* check */
#endif
					   }
					   can_State[controller_cntr] = CAN_STOPPED;
				   } 
				}
			 }
		 }
      }
   }
#endif /* #if (CAN_WAKEUP_POLLING == STD_ON)  */
}

/**********************************************************************************************************************
 * Can_MainFunction_BusOff
 *********************************************************************************************************************/
/*! \brief      This function performs the polling of bus-off events that are configured statically as 'to be polled'.
 *
 *  \param[in]  void
 *
 *  \context
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_011 */
/* DesignId : CAN_DesignId_018 */
/* Requirements : AR_CAN_SR74, AR_CAN_SR218, AR_CAN_SR219, AR_CAN_SR220, AR_CAN_SR221 */
FUNC(void, CAN_CODE)  Can_MainFunction_BusOff( void )
{
#if (CAN_BUSOFF_POLLING == STD_ON)
   uint8 controller_cntr;
   CAN_ControllerRegMap *node;
   uint32 Can_CtlReg;
   uint32 Can_EsReg;

#if (CAN_DEV_ERROR_DETECT == STD_ON)
   canFxnId = CAN_MAINFCT_BO_ID;
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   if (Can_ConfigPtr == NULL_PTR)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0x00U, (uint8)CAN_MAINFCT_BO_ID, (uint8)CAN_E_UNINIT);
   }
   else
#endif
   {
      for(controller_cntr=0U;controller_cntr<Can_ConfigPtr->CanMaxControllerCount;controller_cntr++)
      {
         /* If the controller is not activated just skip its checking */
         if(Can_ConfigPtr->CanControllerList[controller_cntr]->CntrActive == TRUE)         
		 {		
			 /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
			 node = (CAN_ControllerRegMap *)   Can_ConfigPtr->CanControllerList[controller_cntr]->CntrAddr;
			 /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
			 if(node != NULL_PTR)			 
			 {
				Can_CtlReg = node->CTL;
				Can_EsReg = node->ES;					  
				if(((Can_EsReg & (BUS_OFF)) == (BUS_OFF))&&
				   ((Can_CtlReg & (ENABLE_INIT_BIT)) == (ENABLE_INIT_BIT)))
				{
					/* Check if recovery has already started */
					if(CanBusOffRecoveryStatus[controller_cntr] != TRUE)
					{
						/* BusOff Recovery sequence has not started */						
						can_State[controller_cntr] = CAN_STOPPED;
						/*Call the bus off indication function*/
						CanIf_ControllerBusOff(controller_cntr);
				   }
				}
			 }
		 } 
      }
   }
#endif /* #if (CAN_BUSOFF_POLLING == STD_ON) */
}

/**********************************************************************************************************************
 * Can_MainFunction_Mode
 *********************************************************************************************************************/
/*! \brief      This function performs the polling of CAN controller mode transitions
 *              This will indicate only the CanController SW state and cannot indicate any HW state as there is not
 *              HW state exposed from the Can Controller.
 *
 *  \param[in]  void
 *
 *  \context
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_008 */
/* DesignId : CAN_DesignId_020 */
/* Requirements : AR_CAN_SR47, AR_CAN_SR51, AR_CAN_SR226, AR_CAN_SR228 */
FUNC(void, CAN_CODE)  Can_MainFunction_Mode( void )
{
   uint8 controller_cntr;
   CAN_ControllerRegMap *node;
   uint32 Can_EsReg4;
   uint32 Can_CtlReg4;
#if (CAN_DEV_ERROR_DETECT == STD_ON)
   canFxnId = CAN_MAINFCT_MODE_ID;
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   if (Can_ConfigPtr == NULL_PTR)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0x00U, (uint8)CAN_MAINFCT_MODE_ID, (uint8)CAN_E_UNINIT);
   }
   else
#endif
   {
      for(controller_cntr=0U;controller_cntr<Can_ConfigPtr->CanMaxControllerCount;controller_cntr++)
      {         
		 /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/		 		 
		 node = (CAN_ControllerRegMap *)   Can_ConfigPtr->CanControllerList[controller_cntr]->CntrAddr;		 			 
		 /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
		 if (node != NULL_PTR)
		 {
			 switch(can_State[controller_cntr])
			 {
				case CAN_STARTED:
				{
				   /* If BusOff recovery sequence has started, check if CAN controller is started. If Not 
					  restart CAN controller */
				   if(CanBusOffRecoveryStatus[controller_cntr] == TRUE)
				   {
						/*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason-NULL pointer is defined as void pointer to zero."*/
						 if((Can_ConfigPtr->CanControllerList[controller_cntr]->CntrActive == TRUE))
						 {
							 /* Restart CAN controller */
							 node->CTL &= ~((CCE_BIT) | (ENABLE_INIT_BIT));
							 Can_EsReg4 = node->ES;
							 if((Can_EsReg4 & (BUS_OFF)) != (BUS_OFF))
							 {
								/* Busoff recovery has completed */
								CanBusOffRecoveryStatus[controller_cntr] = FALSE;
							 }
						}	
				   }
				   CanIf_ControllerModeIndication( controller_cntr, CANIF_CS_STARTED );
				   break;
				}
				case CAN_STOPPED:
				{
				   Can_CtlReg4 = node->CTL;			   
				   if(((Can_CtlReg4) & (ENABLE_INIT_BIT)) == (ENABLE_INIT_BIT))
				   {
						CanIf_ControllerModeIndication( controller_cntr, CANIF_CS_STOPPED );
				   }
				   break;
				}
				case CAN_SLEEP:
				{
				   Can_CtlReg4 = node->CTL;
				   if(((Can_CtlReg4) & (LOCAL_PD_BIT)) == (LOCAL_PD_BIT))
				   {
					  CanIf_ControllerModeIndication( controller_cntr, CANIF_CS_SLEEP );
				   }  
				   break;      
				}
			   default:
			   {
				   break;
			   }
			 }/*End of Switch*/
		 }
      }
   }
}
/**********************************************************************************************************************
 * Can_MainFunction_Read
 *********************************************************************************************************************/
/*! \brief      This function performs the polling of CAN controller mode transitions
 *
 *  \param[in]  void
 *
 *  \context
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_014 */
/* DesignId : CAN_DesignId_017 */
/* Requirements : AR_CAN_SR105, AR_CAN_SR107, AR_CAN_SR111, AR_CAN_SR213, AR_CAN_SR214, AR_CAN_SR215, AR_CAN_SR216 */
FUNC(void, CAN_CODE)  Can_MainFunction_Read( void )
{
#if (CAN_RX_POLLING == STD_ON)
   uint8 htrh;
   uint8 Controller1;
   uint32 messageBox ;
   uint32 regIndex ;
   uint32 bitIndex ;
   uint8 CanDlc;
   uint32 CanId;
   

   CAN_ControllerRegMap *node;
   uint8 i;
   uint8 loopResult;

#if (CAN_DEV_ERROR_DETECT == STD_ON)
   canFxnId = CAN_MAINFCT_READ_ID;
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   if (Can_ConfigPtr == NULL_PTR)
   {
     (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)0x00U, (uint8)CAN_MAINFCT_READ_ID, (uint8)CAN_E_UNINIT);
   }
   else
#endif
   {
      for(htrh=0U;htrh < Can_ConfigPtr->MaxMbCnt;htrh++ )
      {
         /* only for the Rx Mailbox */
         if(Can_ConfigPtr->MailBoxList[htrh]->MBDir == 0U)
         {
            Controller1 = Can_ConfigPtr->MailBoxList[htrh]->Controller->ControllerId;
            /* If the controller is not activated just skip its checking */
            if(Can_ConfigPtr->CanControllerList[Controller1]->CntrActive == TRUE)            
			{
				/*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
				node = (CAN_ControllerRegMap *)   Can_ConfigPtr->CanControllerList[Controller1]->CntrAddr;
				/*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
				if(node == NULL_PTR)
				{
#if (CAN_DEV_ERROR_DETECT == STD_ON)
				  (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller1, \
				                   (uint8)CAN_MAINFCT_READ_ID, (uint8)CAN_E_PARAM_POINTER);
#endif
				}
				else
				{
				   messageBox = Can_ConfigPtr->MailBoxList[htrh]->HwHandle;
				   regIndex = (messageBox - 1U) >> 5U;
				   bitIndex = 1U << ((messageBox - 1U) & 0x1FU);				
					
				   if((node->NWDATx[regIndex] & bitIndex) == bitIndex)
				   {
						/* Wait until IF2 is ready for use */
						LoopCounterInitEnd(Controller1,(uint8)1U);
						do
						{
							loopResult= LoopCounter(Controller1,(uint8)1U);
							/*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/	
						}
						/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
			            /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
						while((loopResult!=0U) && ((node->IF2STAT & 0x80U) == 0x80U));
						LoopCounterInitEnd(Controller1,(uint8)1U);

						node->IF2CMD  = 0x7FU;

						/* Copy MB Info into IF2 */
						node->IF2NO = (uint8)messageBox;

#if (CAN_DEV_ERROR_DETECT == STD_ON)
						/* Check if Message is lost/overwritten */
						/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
						if((node->IF2MCTL & 0x00004000U) == 0x00004000U)
						{
						  (void)Det_ReportError((uint16)CAN_MODULE_ID, (uint8)Controller1, \
						                   (uint8)CAN_MAINFCT_READ_ID, (uint8)CAN_E_DATALOST);
						   /* Clear Message Lost Bit */
						   node->IF2MCTL &= (~CLR_MSG_LOST);
						   node->IF2CMD  = 0x90U ; /* Message Lost bit changed */
						   /* Copy Control into message box */
						   /*SAFETYMCUSW 93S MR:10.3 <APPROVED> "Reason - Casting is done from uint32 to uint8"*/
						   node->IF2NO = (uint8) messageBox ;
						}						
						else
#endif
						{
							/* Wait until data are copied into IF2 */
							LoopCounterInitEnd(Controller1,(uint8)1U);
							do
							{
								loopResult= LoopCounter(Controller1,(uint8)1U);
							    /*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/	
							}
							/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
			                /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
							while((loopResult!=0U) && ((node->IF2STAT & BUSY) == BUSY));
							LoopCounterInitEnd(Controller1,(uint8)1U);

							/* Read the CanID */						
							/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
							if(((node->IF2ARB) & (1U<<30U)) == (1U<<30U))
							{
								/*since its extended id append it by MSB=1*/
								/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
								CanId = (uint32)((node->IF2ARB & 0x1FFFFFFFU)|(0x80000000U));
							}
							else
							{
								/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
								CanId = (node->IF2ARB >> 18U) & 0x7FFU;
							}
							/* Get number of received bytes */
							/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
							CanDlc = (uint8)(node->IF2MCTL & 0x0000000FU);
							/* Read back the data field */
							for (i = 0U; i < CanDlc; i++)
							{
								CanSduPtr[i] = node->IF2DATx.ucData[s_canByteOrder[i]];
							}
							/*SAFETYMCUSW 93 S MR:6.1,6.2,10.1,10.2,10.3,10.4 <APPROVED> "Reason -  
							  casting is required here."*/
							CanIf_RxIndication((uint8)(Can_ConfigPtr->MailBoxList[htrh]->CanObjectId), \
							                    (Can_IdType)CanId,CanDlc,CanSduPtr);
						}
				   }
				}
			}
         }
      } 
   }
#endif /* #if (CAN_RX_POLLING == STD_ON) */
}

#if (CAN_LOOPBACK_ENABLE == STD_ON)
/**********************************************************************************************************************
 * Can_TestLoopBackModeEnable
 *********************************************************************************************************************/
/*! \brief      This function enables the Loopback
 *
 *  \param[in]  uint8 controller for which loopback needs to be enabled
 *              uint8 mode 0 - Enable Digital mode. 1 - Enable Analog mode. 
 *
 *  \context
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_037 */
/* DesignId : CAN_DesignId_021 */
/* Requirements : AR_CAN_SR284 */
FUNC(Std_ReturnType, CAN_CODE) Can_TestLoopBackModeEnable(uint8 controller, uint8 mode)
{
   CAN_ControllerRegMap *node;
   VAR(Std_ReturnType, AUTOMATIC) Can_RetTmp8;

   Can_RetTmp8 = (Std_ReturnType)E_NOT_OK;
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   if((Can_ConfigPtr != NULL_PTR ) && (controller < (Can_ConfigPtr->CanMaxControllerCount)) && (mode < 2U))
   {
      /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
	  node = (CAN_ControllerRegMap *) Can_ConfigPtr->CanControllerList[controller]->CntrAddr;
      /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
	  if(node != NULL_PTR)
      {
         /* Enable the test Mode first */
         node->CTL |= TEST_ENABLE_BIT;
         if(0U == mode)
         {
        	 /* Enable Digital Loopback */
        	 node->TEST |=  LOOPBACK_INT_REG_BIT;
			 Can_RetTmp8 = E_OK;
         }
         else
         {
           	/* Enable Analog Loopback */
           	node->TEST |=  LOOPBACK_EXT_REG_BIT;
			Can_RetTmp8 = E_OK;
		  }
      }
   }
   return(Can_RetTmp8);
}

/**********************************************************************************************************************
 * Can_TestLoopBackModeDisable
 *********************************************************************************************************************/
/*! \brief      This function Disable the Loopback
 *
 *  \param[in]  uint8 controller for which loopback needs to be Disabled
 *              uint8 mode 0 - Disable Digital mode. 1 - Disable Analog mode.
 *
 *  \context
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_037 */
/* DesignId : CAN_DesignId_022 */
/* Requirements : AR_CAN_SR284 */
FUNC(Std_ReturnType, CAN_CODE) Can_TestLoopBackModeDisable(uint8 controller, uint8 mode)
{
   CAN_ControllerRegMap *node;
   VAR(Std_ReturnType, AUTOMATIC) Can_RetTmp9;

   Can_RetTmp9 = (Std_ReturnType)E_NOT_OK;
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   if((Can_ConfigPtr != NULL_PTR ) && (controller < (Can_ConfigPtr->CanMaxControllerCount)) && (mode < 2U))
   {
	   /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
	   node = (CAN_ControllerRegMap *) Can_ConfigPtr->CanControllerList[controller]->CntrAddr;
	   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
	   if(node != NULL_PTR)
       {
    	 if(0U == mode)
    	 {
    		 /* Disable Digital Loopback */
    		 node->TEST &=  ~(LOOPBACK_INT_REG_BIT);
			 Can_RetTmp9 = E_OK;
    	 }
    	 else
    	 {
    		 /* Disable Analog Loopback */
    		 node->TEST &=  ~(LOOPBACK_EXT_REG_BIT);
			 Can_RetTmp9 = E_OK;
    	 }		 
         /* Clear the test mode */
         node->CTL &= ~(TEST_ENABLE_BIT);
       }
   }
   return(Can_RetTmp9);
}
#endif /* #if (CAN_LOOPBACK_ENABLE == STD_ON)*/

/**********************************************************************************************************************
 * Can_ConfigRegReadBack
 *********************************************************************************************************************/
/*! \brief      This is the function for checking the configuration registers.
 *              This APi canbe called by higher layers to check if configuration is correct.
 *
 *  \param[in]  uint8 controller - 3 controllers are there 
 *
 *  \context
 *********************************************************************************************************************/
#if(STD_ON == CAN_SAFETI_API)
/* SourceId : CAN_SourceId_038 */
/* DesignId : CAN_DesignId_023 */
/* Requirements : AR_CAN_SR290, AR_CAN_SR291  */
Std_ReturnType Can_ConfigRegReadBack( VAR(uint8, AUTOMATIC) controller)
{

	CAN_ControllerRegMap *node;
	uint8 loop = 0U;
	VAR(Std_ReturnType, AUTOMATIC) Can_RetTmp10;

    Can_RetTmp10 = (Std_ReturnType)E_NOT_OK;
	/*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
	if((Can_ConfigPtr != NULL_PTR ) && (controller < (Can_ConfigPtr->CanMaxControllerCount)))
    {
	   /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
	   node = (CAN_ControllerRegMap *) Can_ConfigPtr->CanControllerList[controller]->CntrAddr;
	   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
	   if(node != NULL_PTR)
	   {
		   /* Read configuration registers value */
		   Can_CanConfig.Can_ReaBack_CTL 		= node->CTL;
		   Can_CanConfig.Can_ReaBack_BTR 		= node->BTR;
		   Can_CanConfig.Can_ReaBack_ABOTR		= node->ABOTR;
		   for(loop=0U; loop < 4U; loop++)
		   {
			   Can_CanConfig.Can_ReaBack_INTMUXx[loop] 	= node->INTMUXx[loop];
		   }
		   Can_RetTmp10 = E_OK;
	   }
    }
	return(Can_RetTmp10);
}
#endif

/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#define CAN_STOP_SEC_CODE
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"

/**********************************************************************************************************************
 * INTERRUPT SERVICE ROUTINES
 *********************************************************************************************************************/

/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#define CAN_START_SEC_CODE_APPL
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"
/**********************************************************************************************************************
 * Can_0_Int0ISR_Fun
 *********************************************************************************************************************/
/*! \brief      This is the ISR function for the CAN controller 1. All the Interrupts are hooked to DCAN0INT.
 *              This ISR sends the TX confirmation for the successful tx msg.
 *              This ISR will call the RX processing function for the received message.
 *              This ISR will call the Error processing function in case of any error interrupts.
 *
 *  \param[in]  void
 *
 *  \context    ISR
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_003 */
/* DesignId : CAN_DesignId_024 */
/* Requirements : AR_CAN_SR21, AR_CAN_SR30, AR_CAN_SR32, AR_CAN_SR89, AR_CAN_SR111, AR_CAN_SR113, AR_CAN_SR68, 
   AR_CAN_SR69, AR_CAN_SR72 */
/*SAFETYMCUSW 69 S MR:3.4 <APPROVED> "Reason - Pragma usage is required here to force ISR to ARM mode."*/
#pragma CODE_STATE(Can_0_Int0ISR_Fun, 32)
FUNC(void, CAN_CODE) Can_0_Int0ISR_Fun(  void )
{
   uint32 value;
   CAN_ControllerRegMap *node;
   uint16 mbcntr =0U;
   uint32 es;
   uint8 loopResult;
   
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   node = (CAN_ControllerRegMap *) CAN_0_BASE_ADDR;
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   if(node != NULL_PTR)   
   {
		value = node->INT;
        es = node->ES; /* Read the error and status reg */
        if(value == ERROR_STATUS_INT_BIT)
        {
           /*Error processing */
           if((es & 0x80U) == 0x80U)
           {
              /* in BUS OFF state call the notification function */
              CanIf_ControllerBusOff((uint8)CONTROLLER_ID_0);
              can_State[CONTROLLER_ID_0] = CAN_STOPPED;
           }
           else if((es & WAKEUP_PEND) == WAKEUP_PEND)
           {
              /* in Wakeup notification state call the notification function */
              /*disable the status interrupt now as we are awake* and put in init mode so that its not on bus*/
              node->CTL &= ~((LOCAL_PD_BIT)|( SIE ));
              node->CTL |= (0x01U); /* put it in init mode (stopped state)*/
              can_State[CONTROLLER_ID_0] = CAN_STOPPED;
#ifdef WAKEUP_SOURCE_REF_0
			  EcuM_CheckWakeup((EcuM_WakeupSourceType)WAKEUP_SOURCE_REF_0);
#endif
           }
		    else		
		   {
				/* For MISRA-C Compliance */
		   }            
	} 
	else 
	{
	    if ( ( value > 0U ) && (value <= KMAX_MB_PER_CONTROLLER ) )
		{
           /* Process this interrupt */
           /*As the ISR is from Controller 1 */
           mbcntr = CanMbMapping[CONTROLLER_ID_0][value];
           if(Can_ConfigPtr->MailBoxList[mbcntr]->MBDir ==0U)
           {
              /* Process RX*/
              Can_RxProcess(mbcntr);
           }
           else
           {
              /*Provide Tx confirmation */
              canTxRxStatus[mbcntr] = 0U;/* clear for next transmission.*/
              CanIf_TxConfirmation(canTxRxPduId[mbcntr]);
           }
           /* Setup IF1 for clear pending interrupt flag */
           LoopCounterInitEnd((uint8)CONTROLLER_ID_0,(uint8)0U);
           do
           {
              /*SAFETYMCUSW 91D MR:16.10 <APPROVED> "Reason - loopResult is used in while MACRO"*/
              loopResult= LoopCounter((uint8)CONTROLLER_ID_0,0U);
              /*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/	
           }
		   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
		   /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
		   while((loopResult!=0U) && ((node->IF1STAT & BUSY) == BUSY)); /*Misra fixes*/
           LoopCounterInitEnd((uint8)CONTROLLER_ID_0,(uint8)0U);
           node->IF1CMD = 0x08U;
           node->IF1NO  = (uint8)value;
           LoopCounterInitEnd((uint8)CONTROLLER_ID_0,(uint8)0U);
           do
           {
              /*SAFETYMCUSW 91D MR:16.10 <APPROVED> "Reason - loopResult is used in while MACRO"*/
              loopResult= LoopCounter((uint8)CONTROLLER_ID_0,0U);
              /*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/	
           }
		   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
		   /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
		   while((loopResult!=0U) && ((node->IF1STAT & BUSY)== BUSY)); /*Misra fixes*/
           LoopCounterInitEnd((uint8)CONTROLLER_ID_0,(uint8)0U);
           node->IF1CMD = 0x87U;
        }
    }/*End of else*/  
  }
}
/**********************************************************************************************************************
 * Can_1_Int0ISR_Fun
 *********************************************************************************************************************/
/*! \brief      This is the ISR function for the CAN controller 2. All the Interrupts are hooked to DCAN0INT.
 *              This ISR sends the TX confirmation for the successful tx msg.
 *              This ISR will call the RX processing function for the received message.
 *              This ISR will call the Error processing function in case of any error interrupts.
 *
 *  \param[in]  void
 *
 *  \context    ISR
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_010 */
/* DesignId : CAN_DesignId_024 */
/* Requirements : AR_CAN_SR21, AR_CAN_SR30, AR_CAN_SR32, AR_CAN_SR89, AR_CAN_SR111, AR_CAN_SR113, AR_CAN_SR68, 
   AR_CAN_SR69, AR_CAN_SR72 */
/*SAFETYMCUSW 69 S MR:3.4 <APPROVED> "Reason - Pragma usage is required here to force ISR to ARM mode."*/
#pragma CODE_STATE(Can_1_Int0ISR_Fun, 32)
FUNC(void, CAN_CODE) Can_1_Int0ISR_Fun(  void )
{
   uint32 value;
   CAN_ControllerRegMap *node;
   uint16 mbcntr =0U;
   uint32 es;
   uint8 loopResult;
   
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   node = (CAN_ControllerRegMap *) CAN_1_BASE_ADDR;
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   if(node != NULL_PTR)   
   {
		value = node->INT;
        if (value == ERROR_STATUS_INT_BIT)
        {
           /*REad the ES register */
           es = node->ES;
           if((es & 0x80U) == 0x80U)
           {
              /* in BUS OFF state call the notification function */
              CanIf_ControllerBusOff((uint8)CONTROLLER_ID_1);
              can_State[CONTROLLER_ID_1] = CAN_STOPPED;
           }
           else if((es & WAKEUP_PEND) == WAKEUP_PEND)
           {
              /* in Wakeup notification state call the notification function */
              /*disable the status interrupt now as we are awake* and put in init mode so that its not on bus*/
              node->CTL &= ~((LOCAL_PD_BIT)|( SIE ))|(0x01U);
#ifdef WAKEUP_SOURCE_REF_1
			  EcuM_CheckWakeup((EcuM_WakeupSourceType)WAKEUP_SOURCE_REF_1);
#endif
              can_State[CONTROLLER_ID_1] = CAN_STOPPED;
           }
		   else		
		   {
				/* For MISRA-C Compliance */
		   }		   
	} 
	else 
	{
	    if ( ( value > 0U ) && (value <= KMAX_MB_PER_CONTROLLER ) )
		{
           /* Process this interrupt */
           /*As the ISR is from Controller 2 */
           mbcntr = CanMbMapping[CONTROLLER_ID_1][value];
            if(Can_ConfigPtr->MailBoxList[mbcntr]->MBDir ==0U)
           {
              /* Process RX*/
              Can_RxProcess(mbcntr);
           }
           else
           {
              /*Provide Tx confirmation */
              canTxRxStatus[mbcntr] = 0U;/* clear for next transmission.*/
              CanIf_TxConfirmation(canTxRxPduId[mbcntr]);
           }
           /* Setup IF1 for clear pending interrupt flag */ 
           LoopCounterInitEnd((uint8)CONTROLLER_ID_1,(uint8)0U);
           do
           {
              /*SAFETYMCUSW 91D MR:16.10 <APPROVED> "Reason - loopResult is used in while MACRO"*/
              loopResult= LoopCounter((uint8)CONTROLLER_ID_1,(uint8)0U);
              /*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/	
 		   }
		   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
		   /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
		   while((loopResult!=0U) && ((node->IF1STAT & BUSY)== BUSY)); /*MISRA fixes*/
           LoopCounterInitEnd((uint8)CONTROLLER_ID_1,(uint8)0U);
           node->IF1CMD = CLRINTPEND;
           node->IF1NO  = (uint8)value;
    
           LoopCounterInitEnd((uint8)CONTROLLER_ID_1,(uint8)0U);
           do
           {
              /*SAFETYMCUSW 91D MR:16.10 <APPROVED> "Reason - loopResult is used in while MACRO"*/
              loopResult= LoopCounter((uint8)CONTROLLER_ID_1,(uint8)0U);
              /*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/	
		   }
		   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
		   /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
		   while((loopResult!=0U) && ((node->IF1STAT & BUSY)== BUSY)); /*Misra Fixes*/
           LoopCounterInitEnd((uint8)CONTROLLER_ID_1,(uint8)0U);
           node->IF1CMD = ENABLE_NORMAL_MODE;
        }
    }/*End of else (node == NULL_PTR)*/   
  }
}

/**********************************************************************************************************************
 * Can_2_Int0ISR_Fun
 *********************************************************************************************************************/
/*! \brief      This is the ISR function for the CAN controller 3. All the Interrupts are hooked to DCAN0INT.
 *              This ISR sends the TX confirmation for the successful tx msg.
 *              This ISR will call the RX processing function for the received message.
 *              This ISR will call the Error processing function in case of any error interrupts.
 *
 *  \param[in]  void
 *
 *  \context    ISR
 *********************************************************************************************************************/
/* SourceId : CAN_SourceId_036 */
/* DesignId : CAN_DesignId_024 */
/* Requirements : AR_CAN_SR21, AR_CAN_SR30, AR_CAN_SR32, AR_CAN_SR89, AR_CAN_SR111, AR_CAN_SR113, AR_CAN_SR68, 
   AR_CAN_SR69, AR_CAN_SR72 */
/*SAFETYMCUSW 69 S MR:3.4 <APPROVED> "Reason - Pragma usage is required here to force ISR to ARM mode."*/   
#pragma CODE_STATE(Can_2_Int0ISR_Fun, 32)
FUNC(void, CAN_CODE) Can_2_Int0ISR_Fun(  void )
{
   uint32 value;
   CAN_ControllerRegMap *node;
   uint16 mbcntr =0U;
   uint32 es;
   uint8 loopResult;
   
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   node = (CAN_ControllerRegMap *) CAN_2_BASE_ADDR;
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
   if(node != NULL_PTR)   
   {
		value = node->INT;
        if (value == ERROR_STATUS_INT_BIT)
        {
           es = node->ES;
           if((es & 0x80U) == 0x80U)
           {
              /* in BUS OFF state call the notification function */
              CanIf_ControllerBusOff((uint8)CONTROLLER_ID_2);
              can_State[CONTROLLER_ID_2] = CAN_STOPPED;
           }
           else if((es & WAKEUP_PEND) == WAKEUP_PEND)
           {
              /* in Wakeup notification state call the notification function */
              /*disable the status interrupt now as we are awake* and put in init mode so that its not on bus*/
              node->CTL &= ~((LOCAL_PD_BIT)|( SIE ))|(0x01U);
#ifdef WAKEUP_SOURCE_REF_2
			  EcuM_CheckWakeup((EcuM_WakeupSourceType)WAKEUP_SOURCE_REF_2);
#endif
              can_State[CONTROLLER_ID_2] = CAN_STOPPED;
           }
		   else
		   {
				/* For MISRA-C Compliance */
		   }			
	} 
	else 
	{
	    if ( ( value > 0U ) && (value <= KMAX_MB_PER_CONTROLLER ) )
		{
           /* Process this interrupt */
           /*As the ISR is from Controller 3 */
           /*SAFETYMCUSW 134S MR:21.1 <APPROVED> "Reason - The "value" variable is uint32 is used as array index"*/
           mbcntr = CanMbMapping[CONTROLLER_ID_2][value];
           if(Can_ConfigPtr->MailBoxList[mbcntr]->MBDir ==0U)
           {
              /* Process RX*/
              Can_RxProcess(mbcntr);
           }
           else
           {
              /*Provide Tx confirmation */
              canTxRxStatus[mbcntr] = 0U;/* clear for next transmission.*/
              CanIf_TxConfirmation(canTxRxPduId[mbcntr]);
           }

           /*Setup IF1 for clear pending interrupt flag */
           LoopCounterInitEnd((uint8)CONTROLLER_ID_2,(uint8)0U);
           do
           {
              /*SAFETYMCUSW 91D MR:16.10 <APPROVED> "Reason - loopResult is used in while MACRO"*/
              loopResult= LoopCounter((uint8)CONTROLLER_ID_2,(uint8)0U);
              /*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/	
		   }
		   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
		   /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
		   while((loopResult!=0U) && ((node->IF1STAT & BUSY) == BUSY));/*Misra fixes*/
           LoopCounterInitEnd((uint8)CONTROLLER_ID_2,(uint8)0U);
           node->IF1CMD = CLRINTPEND;
           node->IF1NO  = (uint8)value;

           LoopCounterInitEnd((uint8)CONTROLLER_ID_2,(uint8)0U);
           do
           {
              /*SAFETYMCUSW 91D MR:16.10 <APPROVED> "Reason - loopResult is used in while MACRO"*/
              loopResult= LoopCounter((uint8)CONTROLLER_ID_2,(uint8)0U);
			  /*SAFETYMCUSW 184 S LDRA adding spaces causes this rule to fail."*/		
		   }
		   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
		   /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
		   while((loopResult!=0U) && ((node->IF1STAT & BUSY)== BUSY)); /*Misra fixes*/
           LoopCounterInitEnd((uint8)CONTROLLER_ID_2,(uint8)0U);
           node->IF1CMD = 0x87U;
        }
    }/*end of else (node == NULL_PTR)*/
  }
}

/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#define CAN_STOP_SEC_CODE_APPL
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"

/*********************************************************************************************************************
 *  End of File: Can.c
 *********************************************************************************************************************/
