/**********************************************************************************************************************
 *  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-2014.  All rights reserved.
 *
 *  \endverbatim
 *  -------------------------------------------------------------------------------------------------------------------
 * 
 *  -------------------------------------------------------------------------------------------------------------------
 *  FILE DESCRIPTION
 *  -------------------------------------------------------------------------------------------------------------------
 *         File:  Lin.c
 *    Component:  Tms570_AutosarLinDriver
 *       Module:  LinDriver
 *    Generator:  None
 *
 *  Description:  The LIN driver is responsible for controlling the LIN module. Provides API's for transmission and
 *                reception of the data over LIN module
 * 
 *---------------------------------------------------------------------------------------------------------------------
 * Author:  Prathap Srinivasan
 *---------------------------------------------------------------------------------------------------------------------
 * Revision History
 *---------------------------------------------------------------------------------------------------------------------
 * Version        Date         Author               Change ID        Description
 *---------------------------------------------------------------------------------------------------------------------
 * 02.10.00       24Jan2013   Prathap Srinivasan  0000000000000   - Initial Version adapted from TMS570LS1227
 * 02.10.01		  14Mar2013   Vishwanath Reddy	  SDOCM00099800   - Fixed issue with the receive data 		
 * 02.20.00		  23Aug2013   Vishwanath Reddy	  SDOCM00103357   - Version info updated.
 *                                                                  Safety API's added.
 *                                                                  Requirement tags added for traceability. 
 *                                                                  DET's not mentioned in AUTOSAR removed. 
 *                                                                  MISRA-C fixes.
 * 02.20.02		  14Jul2014   Vishwanath Reddy	  SDOCM00112032   - Lin_Interrupt updated for reporting Bit Error,   
 *                                                                  Overrun Error, Checksum Error,No Response Error,
 *                                                                  Frame Error,Physical Bus Error, Parity Error, 
 *                                                                  Sync Field Error to DEM.
 *                                                                  Design tags added.
 *                                                                  Local Macros realigned. 
 * 02.20.03		  08Aug2014   Vishwanath Reddy	  SDOCM00112419   - User callout added for additional LIN errors.
 *                                                                  Interrupt API modified.
 *                                                                  Lin_AvoidCallOut added.  
 * 02.21.00		  30Sep2014   Vishwanath Reddy	  SDOCM00113130   - Version info updated. Additional DEM Errors are now
 *                                                                  referenced from Tresos. 
 * 02.21.01		  05Nov2014   Vishwanath Reddy	  SDOCM00113739   - Version info updated. Set correct length for LIN 
 *                                                                  Sleep command. Also only set first data byte to 
 *                                                                  0x00, rest of the data to FF's.   
 * 02.21.02		  29Apr2016   Vishwanath Reddy	  SDOCM00122618   - Version info updated.Add requirement AR_LIN_SR170.
 * 02.30.00       01Dec2016   Sudhakar Singh         None         - Update version info
 * 05.30.00       15Mar2017   Sudhakar Singh      SDOCM00122834    Version supports TMS570LSxx Family of Devices.
  ********************************************************************************************************************/
#define LIN_SOURCE

/**********************************************************************************************************************
 *  INCLUDES
 *********************************************************************************************************************/
/* SourceId : LIN_SourceId_023 */
/* DesignId : LIN_DesignId_002 */
/* Requirements : AR_LIN_SR6 */
#include "Lin.h"
#include "Dem.h"
#include "EcuM_Cbk.h"

#if ( LIN_DEV_ERROR_DETECT == STD_ON )
# include "Det.h"
#endif

/**********************************************************************************************************************
 *  VERSION CHECK
 *********************************************************************************************************************/
#define LIN_SW_C_MAJOR_VERSION               (5U)
#define LIN_SW_C_MINOR_VERSION               (30U)
#define LIN_SW_C_PATCH_VERSION               (0U)

/* AUTOSAR version information check has to match definition in header file */
/* SourceId : LIN_SourceId_012 */
/* DesignId : LIN_DesignId_001 */
/* Requirements : AR_LIN_SR12 */
#if (  (LIN_AR_RELEASE_MAJOR_VERSION    != (4U)) \
    || (LIN_AR_RELEASE_MINOR_VERSION    != (0U)) \
    || (LIN_AR_RELEASE_REVISION_VERSION != (3U)) )
  #error "LIN: AUTOSAR Version Numbers of LIN are different"
#endif

#if (  (LIN_SW_MAJOR_VERSION != LIN_SW_C_MAJOR_VERSION) || \
       (LIN_SW_MINOR_VERSION != LIN_SW_C_MINOR_VERSION))
  #error "Vendor specific version numbers of Lin.c and Lin.h are inconsistent"
#endif

#if (  (LIN_CFG_MAJOR_VERSION != LIN_SW_C_MAJOR_VERSION) || \
       (LIN_CFG_MINOR_VERSION != LIN_SW_C_MINOR_VERSION))
  #error "Version numbers of Lin.c and Lin_Cfg.h are inconsistent!"
#endif

/**********************************************************************************************************************
 *  LOCAL CONSTANT MACROS
 *********************************************************************************************************************/
/* Defines for internal states */
#define Lin_OnRxAfterSendHeader                           ((Lin_StateType)0x00U)
#define Lin_OnTxAfterSendHeader                           ((Lin_StateType)0x01U)
#define Lin_OnTxAfterSendResponse                         ((Lin_StateType)0x02U)
#define Lin_OnTxSleepModeFrame                            ((Lin_StateType)0x03U)
#define Lin_OnS2SAfterSendHeader                          ((Lin_StateType)0x04U)
#define Lin_OnRxAfterHeader                               ((Lin_StateType)0x05U)
#define Lin_OnTxAfterHeader                               ((Lin_StateType)0x06U)
#define Lin_OnTxSleepModeFrameAfterHeader                 ((Lin_StateType)0x07U)
#define Lin_OnS2SAfterHeader                              ((Lin_StateType)0x08U)
#define Lin_OnUninit                                      ((Lin_StateType)0x09U)
#define Lin_OnInit                                        ((Lin_StateType)0x0AU)
#define Lin_OnWake                                        ((Lin_StateType)0x0BU)
#define Lin_OnSleep                                       ((Lin_StateType)0x0CU)
#define Lin_OnTxWakeup                                    ((Lin_StateType)0x0DU)
#define Lin_Timeout                                       ((Lin_StateType)0x0EU)
#define Lin_PhanthomError                                 ((Lin_StateType)0x0FU)
#define Lin_SleepCommandDataDlc                           (((uint32)(0x08U-0x01U)<<16U))
#define Lin_SleepCommandDataLow                           ((uint32)0x00FFFFFFU)
#define Lin_SleepCommandDataHigh                          ((uint32)0xFFFFFFFFU)

#if (LIN_LOOPBACKTEST_ENABLE == STD_ON)
#define Lin_OnLoopback                                    ((Lin_StateType)0x10U)
#endif

#if (LIN_DEV_ERROR_DETECT == STD_ON)
#define Lin_Dev_UnInitValue                               ((uint8)0x00U)
#define Lin_Dev_CheckValue                                ((uint8)0xA5U)
#endif


#define Lin_OnHeaderMessageHandlingMax                    (Lin_OnS2SAfterSendHeader)
#define Lin_OnMessageHandlingMax                          (Lin_OnTxSleepModeFrameAfterHeader)

/* LIN_SCIGCR0 access */
#define Lin_ResetInit                          ((uint32)0x00000000U)
#define Lin_ResetEnd                           ((uint32)0x00000001U)

/* LIN_SCIGCR0 access */
#define Lin_TXENA                              ((uint32)0x02000000U)      /* enable transfer                        */
#define Lin_RXENA                              ((uint32)0x01000000U)      /* allows reception                       */
#define Lin_CTYPE                              ((uint32)0x00000800U)      /* enhanced or classic checksum           */
#define Lin_MBUFMode                           ((uint32)0x00000400U)      /* multi buffer mode                      */
#define Lin_HGCTRL                             ((uint32)0x00001000U)      /* multi buffer mode                      */
#define Lin_ADAPT                              ((uint32)0x00000200U)      /* automatic baudrate adjustment          */
#define Lin_SLEEP                              ((uint32)0x00000100U)      /* sleep mode                             */
#define Lin_SWnRESET                           ((uint32)0x00000080U)      /* reset LIN_SCI state engine             */
#define Lin_LINMode                            ((uint32)0x00000040U)      /* LIN mode                               */
#define Lin_CLOCK                              ((uint32)0x00000020U)      /* LIN node type 0-slave, 1-master        */
#define Lin_TIMINGMode                         ((uint32)0x00000002U)      /* async / sync timing mode               */

/* LIN_SCIGCR2 access */
#define Lin_GENWU                              ((uint32)0x00000100U)      /* Generate Wake Up */
#define Lin_POWERDOWN                          ((uint32)0x00000001U)      /* Power down */

/* LIN_SCISETINT, LIN_SCICLEARINT, LIN_SCISETINTLVL, LIN_SCICLEARINTLVL access */
#define Lin_SetBErrInt                         ((uint32)0x80000000U)      /* bit error irq                          */
#define Lin_SetPBErrInt                        ((uint32)0x40000000U)      /* physical bus error irq                 */
#define Lin_SetCErrInt                         ((uint32)0x20000000U)      /* checksum error irq                     */
#define Lin_SetISFErrInt                       ((uint32)0x10000000U)      /* inconsistent synch field error irq     */
#define Lin_SetNRErrInt                        ((uint32)0x08000000U)      /* no response error irq                  */
#define Lin_SetFErrInt                         ((uint32)0x04000000U)      /* framing error irq                      */
#define Lin_SetOErrInt                         ((uint32)0x02000000U)      /* overrun error irq                      */
#define Lin_SetPErrInt                         ((uint32)0x01000000U)      /* parity error irq                      */
#define Lin_SetAllErrInt                       ((uint32)0xFF0000D0U)      /* enable all error irqs                  */
#define Lin_SetRxDMA                           ((uint32)0x00020000U)      /* set RX DMA                             */
#define Lin_SetTxDMA                           ((uint32)0x00010000U)      /* set TX DMA                             */
#define Lin_SetIDInt                           ((uint32)0x00002000U)      /* ID interrupt enable                    */
#define Lin_SetRXInt                           ((uint32)0x00000200U)      /* set RX interrupt enable                */
#define Lin_SetTXInt                           ((uint32)0x00000100U)      /* set TX interrupt enable                */
#define Lin_SetWAKUPInt                        ((uint32)0x00000002U)      /* enables wake up irq                    */
/* SPIPIO0 - SPIPIO8 access */
#define Lin_TXFunc                             ((uint32)0x00000004U)
#define Lin_RXFunc                             ((uint32)0x00000002U)
#define Lin_CLKFunc                            ((uint32)0x00000001U)


/* LIN_SCIFLR access */
#define Lin_BE                                 ((uint32)0x80000000U)  /* bit error flag                         */
#define Lin_PBE                                ((uint32)0x40000000U)  /* physical bus error flag                */
#define Lin_CE                                 ((uint32)0x20000000U)  /* checksum error flag                    */
#define Lin_ISFE                               ((uint32)0x10000000U)  /* inconsistent synch field error flag    */
#define Lin_NRE                                ((uint32)0x08000000U)  /* no response error flag                 */
#define Lin_FE                                 ((uint32)0x04000000U)  /* framing error flag                     */
#define Lin_OE                                 ((uint32)0x02000000U)  /* overrun error flag                     */
#define Lin_PE                                 ((uint32)0x01000000U)  /* parity error flag                     */
#define Lin_SetAllErr                          ((uint32)0xFF000000U)  /* enable all error irqs                  */
#define Lin_RXID                               ((uint32)0x00004000U)  /* Identifier received with RX ID filter match */
#define Lin_TXID                               ((uint32)0x00002000U)  /* Identifier received with TX ID filter match */
#define Lin_TXEMPTY                            ((uint32)0x00000800U)  /* transmit empty flag                    */
#define Lin_TxRDY                              ((uint32)0x00000100U)
#define Lin_TOA3WUS                            ((uint32)0x00000080U)  /* timeout after 3 wake up signals flag   */
#define Lin_TOAWUS                             ((uint32)0x00000040U)  /* timeout after wake up signal flag      */
#define Lin_BAUDUPDATE                         ((uint32)0x00000020U)
#define Lin_TIMEOUT                            ((uint32)0x00000010U)/*enables timeout irq after 4sec no communication*/
#define Lin_BUSY                               ((uint32)0x00000008U)
#define Lin_WAKEUP                             ((uint32)0x00000002U)

/* Masks */ 
#define Lin_MaskRXID                           ((uint32)0x00FF0000U)
#define Lin_MaskTXID                           ((uint32)0x000000FFU)
#define Lin_NoMaskID                           ((uint32)0x00000000U)

#define Lin_WUPattern                          ((uint32)0x80000000U)
#define Lin_SleepCommand                       ((uint8)0x3CU)

/* Loopback Test Modes */
#define Lin_EnableTestMode 					   (0x00000A00U)
#define Lin_DisableTestMode 				   (0x00000500U)
#define Lin_EnableAnalogLoopback			   (0x00000002U)

/* LIN_SCI/BLIN Interrupts offset values */
#define Lin_IntVect_NoInterrupt                (0U)        /* No interrupt                                     */
#define Lin_IntVect_Wakeup                     (1U)        /* Wakeup                                           */
#define Lin_IntVect_IncSynchFieldError         (2U)        /* Inconsistent-Synch-Field Error (LIN mode)        */
#define Lin_IntVect_ParityError                (3U)        /* Parity Error                                     */
#define Lin_IntVect_ID                         (4U)        /* ID (LIN mode)                                    */
#define Lin_IntVect_PhysicalBusError           (5U)        /* Physical Bus Error (LIN mode)                    */
#define Lin_IntVect_FrameError                 (6U)        /* Frame Error                                      */
#define Lin_IntVect_BreakDetect                (7U)        /* Break Detect                                     */
#define Lin_IntVect_ChecksumError              (8U)        /* Checksum Error (LIN mode)                        */
#define Lin_IntVect_OverrunError               (9U)        /* Overrun Error                                    */
#define Lin_IntVect_BitError                   (10U)       /* Bit Error                                        */
#define Lin_IntVect_Receive                    (11U)       /* Receive                                          */
#define Lin_IntVect_Transmit                   (12U)       /* Transmit                                         */
#define Lin_IntVect_NoResponseError            (13U)       /* No-Response Error (LIN mode)                     */
#define Lin_IntVect_TimeoutAfterWakeup         (14U)       /* Timeout After Wakeup Signal (150ms) (LIN mode)   */
#define Lin_IntVect_TimeoutAfter3Wakeup        (15U)       /* Timeout After 3 Wakeup Signals (1.5s) (LIN mode) */
#define Lin_IntVect_TimeoutBusIdle             (16U)       /* Timeout (Bus Idle, 4s) (LIN mode)                */ 

/**********************************************************************************************************************
 *  LOCAL DATA TYPES AND STRUCTURES
 *********************************************************************************************************************/

/* LINID register type */
typedef struct Lin_LinIdTypeTag
{
  uint8 Lin_Reserved1;             /* framing error flag                         */
  uint8 Lin_ReceivedID;            /* Received ID                                */
  uint8 Lin_IDSlaveTaskByte;       /* overrun error flag                         */
  uint8 Lin_IDByte;                /* Transmit ID byte - writing to this address is initializing header transmission */
} Lin_LinIdType;

typedef volatile struct Lin_RegisterStructTypeTag
{
  uint32              Lin_SCIGCR0;                     /* 0x00: Global Control Register 0            */
  uint32              Lin_SCIGCR1;                     /* 0x04: Global Control Register 1            */
  uint32              Lin_SCIGCR2;                     /* 0x08: Global Control Register 2            */
  uint32              Lin_SCISETINT;                   /* 0x0C: Interrupt Enable Register            */
  uint32              Lin_SCICLEARINT;                 /* 0x10: Interrupt Disable Register           */
  uint32              Lin_SCISETINTLVL;                /* 0x14: Set Interrupt Level Register         */
  uint32              Lin_SCICLEARINTLVL;              /* 0x18: Clear Interrupt Level Register       */
  uint32              Lin_SCIFLR;                      /* 0x1C: Flags Register                       */
  uint32              Lin_SCIINTVECT0;                 /* 0x20: Interrupt Vector Offset Register 0   */
  uint32              Lin_SCIINTVECT1;                 /* 0x24: Interrupt Vector Offset Register 1   */
  uint32              Lin_SCIFORMAT;                   /* 0x28: Length Control Register              */
  uint32              Lin_BRSR;                        /* 0x2C: Baud Rate Selection Register         */
  uint32              Lin_SCIED;                       /* 0x30: Emulation Data Buffer Register       */
  uint32              Lin_SCIRD;                       /* 0x34: Receiver Data Buffer Register        */
  uint32              Lin_SCITD;                       /* 0x38: Transmit Data Buffer Register        */
  uint32              Lin_SCIPIO0;                     /* 0x3C: Pin Control Register 0               */
  uint32              Lin_SCIPIO1;                     /* 0x40: Pin Control Register 1               */
  uint32              Lin_SCIPIO2;                     /* 0x44: Pin Control Register 2               */
  uint32              Lin_SCIPIO3;                     /* 0x48: Pin Control Register 3               */
  uint32              Lin_SCIPIO4;                     /* 0x4C: Pin Control Register 4               */
  uint32              Lin_SCIPIO5;                     /* 0x50: Pin Control Register 5               */
  uint32              Lin_SCIPIO6;                     /* 0x54: Pin Control Register 6               */
  uint32              Lin_SCIPIO7;                     /* 0x58: Pin Control Register 7               */
  uint32              Lin_SCIPIO8;                     /* 0x5C: Pull-up/down Select Register 8       */
  uint32              Lin_LINCOMP;                     /* 0x60: LIN Compare Register                 */
  uint32              Lin_LINRD0;                      /* 0x64: LIN Receive Data Register 0          */
  uint32              Lin_LINRD1;                      /* 0x68: LIN Receive Data Register 1          */
  uint32              Lin_LINMASK;                     /* 0x6C: LIN Mask Register                    */
  Lin_LinIdType       Lin_LINID;                       /* 0x70: LIN ID Register                      */
  uint32              Lin_LINTD0;                      /* 0x74: LIN Transmit Data Register 0         */
  uint32              Lin_LINTD1;                      /* 0x78: LIN Transmit Data Register 1         */
  uint32              Lin_MBRSR;                       /* 0x7C: Maximum Baud Rate Selection Reg      */
  uint32              Reserved0;                       /* 0x80: Reserved						     */
  uint32              Reserved1;                       /* 0x84: Reserved						     */
  uint32              Reserved2;                       /* 0x88: Reserved						     */
  uint32              Reserved3;                       /* 0x8C: Reserved						     */
  uint32			  Lin_IODFTCTRL;				   /* 0x90: Input/Output Error Enable Register   */
} Lin_RegisterStructType;

#if(STD_ON == LIN_SAFETI_API)
/*SAFETYMCUSW 25 D MR:8.7 <APPROVED> "Reason - This is used in other files."*/
Lin_LinConfigReg Lin_LinConfig;
#endif

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

/* Wakup notification flag */
STATIC  VAR(uint8, AUTOMATIC)                             Lin_IrqWakeupEvent;

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

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

/* Pointer to Global Configuration */
STATIC P2CONST(Lin_ChannelConfigType, LIN_VAR_NOINIT, LIN_PBCFG) Lin_Data_Config;
STATIC VAR(Lin_ChannelDataType, LIN_VAR_NOINIT) Lin_ChannelData[Lin_TotalNumberOfChannels];

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

#if ( LIN_DEV_ERROR_DETECT == STD_ON )

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

#if ( LIN_DEV_ERROR_DETECT == STD_ON )
/* Variable Lin_Dev_InitDetect must be initialized after reset for working debug check */
/*SAFETYMCUSW 25 D MR:8.7 <APPROVED> "Reason - This is used in unit test."*/
STATIC VAR(uint8, LIN_VAR_ZERO_INIT)                      Lin_Dev_InitDetect  = Lin_Dev_UnInitValue;
#endif

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

#endif

/**********************************************************************************************************************
 *  GLOBAL DATA
 *********************************************************************************************************************/

#define LIN_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 PROTOTYPES
 *********************************************************************************************************************/
/**********************************************************************************************************************
 *  FUNCTIONS
 *********************************************************************************************************************/
 /**********************************************************************************************************************
 *  Lin_AvoidCallOut
 *  Description given in Lin_cfg.h
 *********************************************************************************************************************/
#if (LIN_CALL_USERCALLOUT == STD_ON)		 
void Lin_AvoidCallOut(Lin_ErrorType Error)
{
  /* To avoid Misra warning */
  Error=Error;
}
#endif
/**********************************************************************************************************************
 *  Lin_Init
 *  Description given in Lin.h
 *********************************************************************************************************************/
/* SourceId : LIN_SourceId_001 */
/* DesignId : LIN_DesignId_006 */
/* Requirements : AR_LIN_SR2, AR_LIN_SR18, AR_LIN_SR19, AR_LIN_SR20, AR_LIN_SR51, AR_LIN_SR54, AR_LIN_SR57, 
                  AR_LIN_SR62,AR_LIN_SR80, AR_LIN_SR81, AR_LIN_SR82, AR_LIN_SR83, AR_LIN_SR84, AR_LIN_SR87, 
				  AR_LIN_SR88,AR_LIN_SR43,AR_LIN_SR113, AR_LIN_SR122*/
FUNC(void, LIN_CODE) Lin_Init
(
  P2CONST(Lin_ConfigType, AUTOMATIC, LIN_PBCFG)       Config
)
{
  VAR(uint8, AUTOMATIC)                               ChannelTmp1;  
  P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS) Lin_RegisterStructPtrTmp1;    
  
#if ( LIN_DEV_ERROR_DETECT == STD_ON )  
  if ( Lin_Dev_InitDetect == Lin_Dev_CheckValue )
  {	  
	  (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_INIT_ID, LIN_E_STATE_TRANSITION);	  	  
  }
  /*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."*/
  else if ( Config == (P2CONST(Lin_ConfigType, AUTOMATIC, LIN_PBCFG))NULL_PTR )
  {    
	(void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_INIT_ID, LIN_E_INVALID_POINTER);	  	
  }
  else
#endif  
  { 	
	#if ( LIN_DEV_ERROR_DETECT == STD_ON )  
	Lin_Dev_InitDetect = Lin_Dev_CheckValue;
	#endif
	Lin_Data_Config   = Config->Lin_ChannelConfigPtr;
	/* Loop over all channels and set to uninit */
	for (ChannelTmp1 = 0x00U; ChannelTmp1 < Lin_TotalNumberOfChannels; ChannelTmp1++)
	{
	  Lin_ChannelData[ChannelTmp1].Lin_State                    = Lin_OnUninit;
	  Lin_ChannelData[ChannelTmp1].Lin_ModuleInit_Status        = LIN_UNINIT;
	  /*SAFETYMCUSW 203S MR:11.5 <APPROVED> "Reason - To store the value of type Lin_RegisterStructType"*/
	  /*SAFETYMCUSW 95S MR:11.1 <APPROVED> "Reason -  To access pointer value of type Lin_RegisterStructType"*/
	  Lin_RegisterStructPtrTmp1                      = (P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)) \
														   Lin_Data_Config[ChannelTmp1].Lin_HardwareBaseAdress;

	  /* perform module reset, must be done in privileged mode */
	  /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_RegisterStructPtrTmp1 assigned with valid address"*/	  
	  Lin_RegisterStructPtrTmp1->Lin_SCIGCR0         = Lin_ResetInit;
	  Lin_RegisterStructPtrTmp1->Lin_SCIGCR0         = Lin_ResetEnd;

	  /* setup configuration */
	  Lin_RegisterStructPtrTmp1->Lin_SCIGCR1        &= (~Lin_SWnRESET);

	  /* Set LIN Mode - before this no LIN settings can be done, must be done in privileged mode */
	  Lin_RegisterStructPtrTmp1->Lin_SCIGCR1         = Lin_LINMode;

	  /* Synch Break & Synch Break Delimiter is set */
	  Lin_RegisterStructPtrTmp1->Lin_LINCOMP         = Lin_Data_Config[ChannelTmp1].Lin_Compare;

	  /* Set up frame format, protocol and communication mode */
	  Lin_RegisterStructPtrTmp1->Lin_SCIGCR1        |= (Lin_TXENA | Lin_RXENA | Lin_HGCTRL | Lin_MBUFMode | Lin_CLOCK \
													  | Lin_TIMINGMode);

	  /* configure pin ports - non protected register */
	  Lin_RegisterStructPtrTmp1->Lin_SCIPIO0         = (Lin_TXFunc | Lin_RXFunc);

	  /* Set baudrate register bit timing */
	  Lin_RegisterStructPtrTmp1->Lin_BRSR            = Lin_Data_Config[ChannelTmp1].Lin_BaudRateReg;
	  Lin_RegisterStructPtrTmp1->Lin_MBRSR           = Lin_Data_Config[ChannelTmp1].Lin_MaxBaudSelReg;
	  
	  /* enable receiving of all LIN msgs */
	  Lin_RegisterStructPtrTmp1->Lin_LINMASK         = (Lin_MaskRXID | Lin_MaskTXID);

	  Lin_RegisterStructPtrTmp1->Lin_SCISETINT       = Lin_SetIDInt  | Lin_SetAllErrInt | 
													   Lin_SetRXInt  | Lin_SetWAKUPInt;

	  /* finish configuration */
	  Lin_RegisterStructPtrTmp1->Lin_SCIGCR1        |= Lin_SWnRESET;

	  Lin_ChannelData[ChannelTmp1].Lin_State         = Lin_OnInit;
	  Lin_ChannelData[ChannelTmp1].Lin_Status        = LIN_OPERATIONAL;
	  Lin_ChannelData[ChannelTmp1].Lin_ModuleInit_Status        = LIN_INIT;
	}
  }	    
}

/**********************************************************************************************************************
 *  Lin_CheckWakeup
 *  Description given in Lin.h
 *********************************************************************************************************************/
/* SourceId : LIN_SourceId_002 */
/* DesignId : LIN_DesignId_008 */
/* Requirements : AR_LIN_SR45, AR_LIN_SR51, AR_LIN_SR52, AR_LIN_SR53, AR_LIN_SR54, AR_LIN_SR57, AR_LIN_SR89, 
                  AR_LIN_SR90, AR_LIN_SR91, AR_LIN_SR92, AR_LIN_SR93 */
FUNC(Std_ReturnType, LIN_CODE) Lin_CheckWakeup
(
    VAR(uint8, AUTOMATIC)                                Channel
)
{
  P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS) Lin_RegisterStructPtrTmp2;
  P2VAR(Lin_ChannelDataType, AUTOMATIC, LIN_VAR_NOINIT)  Lin_ChannelDataPtrTmp;
  VAR(uint8, AUTOMATIC)                                  Lin_RxPinTmp;
  VAR(Std_ReturnType, AUTOMATIC)                         Lin_RetTmp;

  Lin_RetTmp                                  = (Std_ReturnType)E_NOT_OK;
    
#if ( LIN_DEV_ERROR_DETECT == STD_ON )
  /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason -  LDRA causing this problem."*/
  if ( Channel >= Lin_TotalNumberOfChannels )
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_CHECKWAKEUP_ID, LIN_E_INVALID_CHANNEL);	  		
  }
  else if ( Lin_ChannelData[Channel].Lin_ModuleInit_Status == LIN_UNINIT  )
  {    
	(void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_CHECKWAKEUP_ID, LIN_E_UNINIT);	  	
  }
  else if ( Lin_ChannelData[Channel].Lin_Status != LIN_CH_SLEEP)
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_CHECKWAKEUP_ID, LIN_E_STATE_TRANSITION);	  	
  }
  else
#endif
  {

	 Lin_ChannelDataPtrTmp                   = &Lin_ChannelData[Channel];

     /* Channel is in sleep state, check if rx pin is low, if yes call EcuM_SetWakeupEvent */
	 /*SAFETYMCUSW 203S MR:11.5 <APPROVED> "Reason - To store the value of type Lin_RegisterStructType"*/
	 /*SAFETYMCUSW 95S MR:11.1 <APPROVED> "Reason -  To access pointer value of type Lin_RegisterStructType"*/
     Lin_RegisterStructPtrTmp2               = (P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)) \
                                                Lin_Data_Config[Channel].Lin_HardwareBaseAdress;

     /*SAFETYMCUSW 96 S MR:10.1 <APPROVED> "Reason -  To get the 8bit value for Lin_RxPinTmp"*/
     /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_RegisterStructPtrTmp2 is already assigned a value "*/	
	 /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
	 /*SAFETYMCUSW 96 S MR:6.2,10.1,10.2,12.6 <APPROVED> "Macro comes from compiler files."*/
	 Lin_RxPinTmp                            = (uint8)(Lin_RegisterStructPtrTmp2->Lin_SCIPIO2 & Lin_RXFunc);
          
     if ( ( Lin_RxPinTmp == (uint8)0x00U ) || ( ( Lin_IrqWakeupEvent & (uint8)(0x01U << Channel) ) != 0U ) )
     {
       Lin_ChannelDataPtrTmp->Lin_State       = Lin_OnWake;
       Lin_ChannelDataPtrTmp->Lin_Status      = LIN_OPERATIONAL;
       Lin_IrqWakeupEvent                    &= (~(0x01U << Channel));
       EcuM_SetWakeupEvent(Lin_Data_Config[Channel].Lin_EcuMWakeupSource);  
       Lin_RetTmp                               = (Std_ReturnType)E_OK;
     }
  }   
  return(Lin_RetTmp);
}


#if ( LIN_VERSION_INFO_API == STD_ON )
/**********************************************************************************************************************
 *  Lin_GetVersionInfo
 *  Description given in Lin.h
 *********************************************************************************************************************/
/* SourceId : LIN_SourceId_003 */
/* DesignId : LIN_DesignId_007 */
/* Requirements : AR_LIN_SR54, AR_LIN_SR57, AR_LIN_SR94, AR_LIN_SR95, AR_LIN_SR96, AR_LIN_SR97, AR_LIN_SR98, 
                  AR_LIN_SR99*/
FUNC(void, LIN_CODE) Lin_GetVersionInfo
(
  P2VAR(Std_VersionInfoType, AUTOMATIC, LIN_APPL_VAR) versioninfo
)
{
# if ( LIN_DEV_ERROR_DETECT == STD_ON )
  /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
  /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
  if ( versioninfo == (P2VAR(Std_VersionInfoType, AUTOMATIC, LIN_APPL_VAR))NULL_PTR )
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_GETVERSIONINFO_ID, LIN_E_INVALID_POINTER);	  		
  }
  else
# endif  
  {
    versioninfo->vendorID           = LIN_VENDOR_ID;
    versioninfo->moduleID           = LIN_MODULE_ID;
    versioninfo->sw_major_version   = LIN_SW_MAJOR_VERSION;
    versioninfo->sw_minor_version   = LIN_SW_MINOR_VERSION;
    versioninfo->sw_patch_version   = LIN_SW_PATCH_VERSION;
  }
}
#endif

/**********************************************************************************************************************
 *  Lin_SendFrame
 *  Description given in Lin.h
**********************************************************************************************************************/
/* SourceId : LIN_SourceId_004 */
/* DesignId : LIN_DesignId_009 */
/* Requirements : AR_LIN_SR28, AR_LIN_SR29, AR_LIN_SR32, AR_LIN_SR36, AR_LIN_SR51, AR_LIN_SR52, AR_LIN_SR53, 
                  AR_LIN_SR54, AR_LIN_SR57, AR_LIN_SR100, AR_LIN_SR101, AR_LIN_SR103, AR_LIN_SR106, AR_LIN_SR107, 
				  AR_LIN_SR108,AR_LIN_SR109  */
FUNC(Std_ReturnType, LIN_CODE) Lin_SendFrame
(
    VAR(uint8, AUTOMATIC)                                       Channel,
	/*SAFETYMCUSW 62D MR:16.7 <APPROVED> "Reason - Function defined as per the Autosar specification"*/
	P2VAR(Lin_PduType, AUTOMATIC, LIN_APPL_VAR)                 PduInfoPtr
)
{
  /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
  P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS) Lin_RegisterStructPtrTmp3 = NULL_PTR;
  VAR(Std_ReturnType, AUTOMATIC)                              Lin_RetTmp3;
  /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
  P2VAR(Lin_ChannelDataType, AUTOMATIC, LIN_VAR_NOINIT)  Lin_ChannelDataPtrTmp3 = NULL_PTR;
  
  Lin_RetTmp3                              = E_NOT_OK;

   
#if ( LIN_DEV_ERROR_DETECT == STD_ON )
  if (Lin_ChannelData[Channel].Lin_ModuleInit_Status == LIN_UNINIT  )
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_SENDFRAME_ID, LIN_E_UNINIT);	  			
  }
  /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason -  LDRA causing this problem."*/
  else if ( Channel >= Lin_TotalNumberOfChannels )
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_SENDFRAME_ID, LIN_E_INVALID_CHANNEL);	  				
  }
  /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
  /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
  else if ( PduInfoPtr == (P2VAR(Lin_PduType, AUTOMATIC, LIN_APPL_VAR))NULL_PTR )
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_SENDFRAME_ID, LIN_E_INVALID_POINTER);	  					
  }
  else if ( Lin_ChannelData[Channel].Lin_Status == LIN_CH_SLEEP)
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_SENDFRAME_ID, LIN_E_STATE_TRANSITION);	  					
  }
  else
#endif
  {
	  Lin_ChannelDataPtrTmp3                          = &Lin_ChannelData[Channel];
	  /*SAFETYMCUSW 203S MR:11.5 <APPROVED> "Reason - To store the value of type Lin_RegisterStructType"*/
	  /*SAFETYMCUSW 95S MR: <APPROVED> "Reason -  To access pointer value of type Lin_RegisterStructType"*/
      Lin_RegisterStructPtrTmp3                       = (P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)) \
                                                         Lin_Data_Config[Channel].Lin_HardwareBaseAdress;
	  /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_RegisterStructPtrTmp3 is already assigned a value "*/	
      Lin_RegisterStructPtrTmp3->Lin_SCIGCR1          &= (~Lin_SWnRESET);

      if ( PduInfoPtr->Cs == (Lin_FrameCsModelType)LIN_ENHANCED_CS )
      {
        /* using enhanced checksum */
        Lin_RegisterStructPtrTmp3->Lin_SCIGCR1        |= Lin_CTYPE;
      }
      else
      {
        /* using classic checksum */
        Lin_RegisterStructPtrTmp3->Lin_SCIGCR1        &= (~Lin_CTYPE);
      }

      /* set DLC */
      Lin_RegisterStructPtrTmp3->Lin_SCIFORMAT         = (((uint32)PduInfoPtr->Dl-0x01U)<<16U);	  
      
	  Lin_ChannelDataPtrTmp3->Lin_Drc           = PduInfoPtr->Drc;
	  
      if ( PduInfoPtr->Drc == (Lin_FrameResponseType)LIN_MASTER_RESPONSE )
	  {
	  	  Lin_RegisterStructPtrTmp3->Lin_LINMASK       = Lin_MaskTXID;
          Lin_ChannelDataPtrTmp3->Lin_State            = Lin_OnTxAfterSendHeader;
	  }
	  else if ( PduInfoPtr->Drc == (Lin_FrameResponseType)LIN_SLAVE_RESPONSE )
	  {
	  	  Lin_RegisterStructPtrTmp3->Lin_LINMASK       = Lin_MaskRXID;
          Lin_ChannelDataPtrTmp3->Lin_State            = Lin_OnRxAfterSendHeader;	  	  
	  }
	  else
	  {
	  	  Lin_RegisterStructPtrTmp3->Lin_LINMASK       = Lin_NoMaskID;
          Lin_ChannelDataPtrTmp3->Lin_State            = Lin_OnS2SAfterSendHeader;	  	  
	  }
	 
      Lin_RegisterStructPtrTmp3->Lin_SCIGCR1          |= Lin_SWnRESET;
	  
	  /* Wait till the SWnRESET bit is set */
	  do
	  {
	  
	  }
	  /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
	  while(((Lin_RegisterStructPtrTmp3->Lin_SCIGCR1 & Lin_SWnRESET) != Lin_SWnRESET));

      Lin_RegisterStructPtrTmp3->Lin_LINID.Lin_IDByte  = PduInfoPtr->Pid;
	  
      /*SAFETYMCUSW 94S MR:11.1 <APPROVED> "Reason - To access data value of SduPtr of type uint32"*/
	  /*SAFETYMCUSW 94 S MR:11.1, 11.2, 11.4 <APPROVED> "Reason - Casting is required here "*/
	  /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
      Lin_RegisterStructPtrTmp3->Lin_LINTD0            = *((P2VAR(uint32, AUTOMATIC, LIN_VAR_REGS))& \
	                                                     (PduInfoPtr->SduPtr[0U]));
	  /*SAFETYMCUSW 94S MR:11.1 <APPROVED> "Reason - To access data value of SduPtr of type uint32"*/
	  /*SAFETYMCUSW 94 S MR:11.1, 11.2, 11.4 <APPROVED> "Reason - Casting is required here "*/
	  /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
      Lin_RegisterStructPtrTmp3->Lin_LINTD1            = *((P2VAR(uint32, AUTOMATIC, LIN_VAR_REGS))& \
	                                                      (PduInfoPtr->SduPtr[4U]));

      Lin_RetTmp3                                      = E_OK;
	  
	  Lin_ChannelDataPtrTmp3->Lin_Status         = LIN_OPERATIONAL;
    }      
  return(Lin_RetTmp3); 
}

/**********************************************************************************************************************
 *  Lin_GoToSleep
 *  Description given in Lin.h
 *********************************************************************************************************************/
/* SourceId : LIN_SourceId_005 */
/* DesignId : LIN_DesignId_010 */
/* Requirements : AR_LIN_SR41, AR_LIN_SR42, AR_LIN_SR51, AR_LIN_SR52, AR_LIN_SR53, AR_LIN_SR54, AR_LIN_SR57, 
                  AR_LIN_SR110,AR_LIN_SR111, AR_LIN_SR112, AR_LIN_SR114, AR_LIN_SR115,AR_LIN_SR116, AR_LIN_SR117, 
				  AR_LIN_SR118, AR_LIN_SR119, AR_LIN_SR21 */
FUNC(Std_ReturnType, LIN_CODE) Lin_GoToSleep
(
  VAR(uint8, AUTOMATIC)                                       Channel
)
{
  P2VAR(Lin_ChannelDataType, AUTOMATIC, LIN_VAR_NOINIT)       Lin_ChannelDataPtrTmp4;
  P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS) Lin_RegisterStructPtrTmp4;

  VAR(Std_ReturnType, AUTOMATIC)                              Lin_RetTmp4;

  Lin_RetTmp4                              = E_NOT_OK;
 
 
#if ( LIN_DEV_ERROR_DETECT == STD_ON )
  if (Lin_ChannelData[Channel].Lin_ModuleInit_Status == LIN_UNINIT  )
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_GOTOSLEEP_ID, LIN_E_UNINIT);	  						
  }
  /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason -  LDRA causing this problem."*/
  else if ( Channel >= Lin_TotalNumberOfChannels )
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_GOTOSLEEP_ID, LIN_E_INVALID_CHANNEL);	  							
  }
  else if ( Lin_ChannelData[Channel].Lin_Status == LIN_CH_SLEEP)
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_GOTOSLEEP_ID, LIN_E_STATE_TRANSITION);	  							
  }
  else
#endif
  {
	Lin_ChannelDataPtrTmp4                           = &Lin_ChannelData[Channel];
	 /*SAFETYMCUSW 203S MR:11.5 <APPROVED> "Reason - To store the value of type Lin_RegisterStructType"*/
	 /*SAFETYMCUSW 95S MR:11.1 <APPROVED> "Reason -  To access pointer value of type Lin_RegisterStructType"*/	
	Lin_RegisterStructPtrTmp4                        = (P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)) \
	                                                    Lin_Data_Config[Channel].Lin_HardwareBaseAdress;

    /* Buffer Lin_PduTmp.Lin_IntSduPtr has been allocated in Lin_SendHeader */
    /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_RegisterStructPtrTmp4 is already assigned a value "*/
	Lin_RegisterStructPtrTmp4->Lin_SCIGCR1          &= (~Lin_SWnRESET);
    Lin_RegisterStructPtrTmp4->Lin_LINMASK           = (Lin_MaskTXID | Lin_MaskRXID); 
    Lin_RegisterStructPtrTmp4->Lin_SCIGCR1          |= Lin_SWnRESET;

    /* Wait till the SWnRESET bit is set */    
	do
	{
	  
	}
	/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
	while(((Lin_RegisterStructPtrTmp4->Lin_SCIGCR1 & Lin_SWnRESET) != Lin_SWnRESET));
	
    
    Lin_RegisterStructPtrTmp4->Lin_SCIGCR1          &= (~Lin_CTYPE);
    Lin_RegisterStructPtrTmp4->Lin_LINID.Lin_IDByte  = Lin_SleepCommand;
    /* set DLC */
    Lin_RegisterStructPtrTmp4->Lin_SCIFORMAT         = Lin_SleepCommandDataDlc;	
	Lin_RegisterStructPtrTmp4->Lin_LINTD0            = Lin_SleepCommandDataLow;
    Lin_RegisterStructPtrTmp4->Lin_LINTD1            = Lin_SleepCommandDataHigh;  

    Lin_ChannelDataPtrTmp4->Lin_State                = Lin_OnTxSleepModeFrame;
    Lin_ChannelDataPtrTmp4->Lin_Status               = LIN_TX_BUSY;
  
    Lin_RetTmp4                                      = E_OK;
 }
  return(Lin_RetTmp4);
}


/**********************************************************************************************************************
 *  Lin_GoToSleepInternal
 *  Description given in Lin.h
 *********************************************************************************************************************/
/* SourceId : LIN_SourceId_006 */
/* DesignId : LIN_DesignId_011 */
/* Requirements : AR_LIN_SR51, AR_LIN_SR52, AR_LIN_SR53, AR_LIN_SR54, AR_LIN_SR57, AR_LIN_SR120, AR_LIN_SR121,
                  AR_LIN_SR123, AR_LIN_SR124, AR_LIN_SR125, AR_LIN_SR126 */
FUNC(Std_ReturnType, LIN_CODE) Lin_GoToSleepInternal
(
  VAR(uint8, AUTOMATIC)                                       Channel
)
{
  P2VAR(Lin_ChannelDataType, AUTOMATIC, LIN_VAR_NOINIT)  Lin_ChannelDataPtrTmp5;
  P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS) Lin_RegisterStructPtrTmp5;
  
  VAR(Std_ReturnType, AUTOMATIC)                         Lin_RetTmp5;

  Lin_RetTmp5                              = E_NOT_OK;
 
#if ( LIN_DEV_ERROR_DETECT == STD_ON )
  if (Lin_ChannelData[Channel].Lin_ModuleInit_Status == LIN_UNINIT  )
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_GOTOSLEEPINTERNAL_ID, LIN_E_UNINIT);	  								
  }
  /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason -  LDRA causing this problem."*/
  else if ( Channel >= Lin_TotalNumberOfChannels )
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_GOTOSLEEPINTERNAL_ID, LIN_E_INVALID_CHANNEL);	  									
  }
  else if ( Lin_ChannelData[Channel].Lin_Status == LIN_CH_SLEEP)
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_GOTOSLEEPINTERNAL_ID, LIN_E_STATE_TRANSITION);	  									
  }
  else
#endif
	{
		/*SAFETYMCUSW 203S MR:11.5 <APPROVED> "Reason - To store the value of type Lin_RegisterStructType"*/
		/*SAFETYMCUSW 95S MR:11.1 <APPROVED> "Reason -  To access pointer value of type Lin_RegisterStructType"*/
		Lin_RegisterStructPtrTmp5                        = (P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)) \
															Lin_Data_Config[Channel].Lin_HardwareBaseAdress;
		Lin_ChannelDataPtrTmp5                           = &Lin_ChannelData[Channel];														
		 
		/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_RegisterStructPtrTmp5 is already assigned a value "*/
		Lin_RegisterStructPtrTmp5->Lin_SCIGCR2           = Lin_POWERDOWN;
		Lin_ChannelDataPtrTmp5->Lin_State                = Lin_OnSleep;
		Lin_ChannelDataPtrTmp5->Lin_Status               = LIN_CH_SLEEP;  
		Lin_RetTmp5                                      = E_OK;
	}
  return(Lin_RetTmp5);
}

/**********************************************************************************************************************
 *  Lin_Wakeup
 *  Description given in Lin.h
 *********************************************************************************************************************/
/* SourceId : LIN_SourceId_007 */
/* DesignId : LIN_DesignId_012 */
/* Requirements : AR_LIN_SR23, AR_LIN_SR24, AR_LIN_SR46, AR_LIN_SR47,AR_LIN_SR52, AR_LIN_SR53, AR_LIN_SR54, 
                  AR_LIN_SR57, AR_LIN_SR127, AR_LIN_SR128, AR_LIN_SR129, AR_LIN_SR130, AR_LIN_SR131, AR_LIN_SR132, 
				  AR_LIN_SR47 */
FUNC(Std_ReturnType, LIN_CODE) Lin_Wakeup
(
  VAR(uint8, AUTOMATIC)                                       Channel
)
{
  P2VAR(Lin_ChannelDataType, AUTOMATIC, LIN_VAR_NOINIT)  Lin_ChannelDataPtrTmp6;
  P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS) Lin_RegisterStructPtrTmp6;
  VAR(Std_ReturnType, AUTOMATIC)                         Lin_RetTmp6;
  volatile VAR(uint8, AUTOMATIC)               			 Lin_WakeUpTimeout;

  Lin_RetTmp6                                        = E_NOT_OK;

#if ( LIN_DEV_ERROR_DETECT == STD_ON )
  if (Lin_ChannelData[Channel].Lin_ModuleInit_Status == LIN_UNINIT  )
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_WAKEUP_ID, LIN_E_UNINIT);	  										
  }
  /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason -  LDRA causing this problem."*/
  else if ( Channel >= Lin_TotalNumberOfChannels )
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_WAKEUP_ID, LIN_E_INVALID_CHANNEL);	  										
  }
  else
#endif
	{
		Lin_ChannelDataPtrTmp6                       = &Lin_ChannelData[Channel];

		if (Lin_ChannelDataPtrTmp6->Lin_Status == LIN_CH_SLEEP)
		{
			/* Only send wakeup Frame if in sleep mode */	  
			/* Calculate pointer for better access */
			Lin_RegisterStructPtrTmp6                  = (P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)) \
														Lin_Data_Config[Channel].Lin_HardwareBaseAdress;
						
			/* Check RX IN pin. If it is 0, it means line is grounded. If not, line is not grounded. */
			/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_RegisterStructPtrTmp6 is already assigned a value "*/
			/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
			if((Lin_RegisterStructPtrTmp6->Lin_SCIPIO2 & Lin_RXFunc) != 0U)
			{
				/* Change to power down mode to send WU frame */
				/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_RegisterStructPtrTmp6 is already assigned a value "*/
				Lin_RegisterStructPtrTmp6->Lin_SCIGCR2    |= Lin_POWERDOWN;

				Lin_RegisterStructPtrTmp6->Lin_LINTD0      = Lin_WUPattern;

				/* Expecting confirmation of the Wakeup */
				Lin_ChannelDataPtrTmp6->Lin_State          = Lin_OnTxWakeup;

				Lin_RegisterStructPtrTmp6->Lin_SCIGCR2     |= Lin_GENWU;

				/* Minimal Wait loop to make sure Low Power mode bit to clear under normal scenario */
				/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
				/*SAFETYMCUSW 134 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
				for(Lin_WakeUpTimeout = 0U;
				    (((Lin_RegisterStructPtrTmp6->Lin_SCIGCR2 & Lin_POWERDOWN) == Lin_POWERDOWN) && (Lin_WakeUpTimeout < 20U));
				    Lin_WakeUpTimeout++)
				{
				    /* Just wait */
				}
				/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
				if((Lin_RegisterStructPtrTmp6->Lin_SCIGCR2 & Lin_POWERDOWN) == Lin_POWERDOWN)
				{
					/* Pulled High case where RX line is High when Wakeup interrupt occurs */
					/* This is a wrong scenario. LIN bus might be short to VBATT */

					/* Enter Low Power Mode */
					Lin_RegisterStructPtrTmp6->Lin_SCIGCR2    |= Lin_POWERDOWN;

					Lin_ChannelDataPtrTmp6->Lin_State          = Lin_OnSleep;
					Lin_RetTmp6                                = E_NOT_OK;
				}
				else
				{
					Lin_ChannelDataPtrTmp6->Lin_Status         = LIN_OPERATIONAL;
					Lin_RetTmp6                                = E_OK;
				}
			}
		}	
	}  

  return(Lin_RetTmp6);
}

/**********************************************************************************************************************
 *  Lin_GetStatus
 *  Description given in Lin.h
 *********************************************************************************************************************/
/* SourceId : LIN_SourceId_008 */
/* DesignId : LIN_DesignId_013 */
/* Requirements : AR_LIN_SR30, AR_LIN_SR52, AR_LIN_SR53, AR_LIN_SR54, AR_LIN_SR57, AR_LIN_SR133, AR_LIN_SR134,
                  AR_LIN_SR135, AR_LIN_SR136, AR_LIN_SR137, AR_LIN_SR138, AR_LIN_SR139, AR_LIN_SR140, AR_LIN_SR39 */
FUNC(Lin_StatusType, LIN_CODE) Lin_GetStatus
(
  VAR(uint8, AUTOMATIC)                                 Channel,
  P2VAR(uint8 *, AUTOMATIC, LIN_APPL_VAR)               Lin_SduPtr
)
{
  P2VAR(Lin_ChannelDataType, AUTOMATIC, LIN_VAR_NOINIT)       Lin_ChannelDataPtrTmp7;
  P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)      Lin_RegisterStructPtrTmp7;
  VAR(Lin_StatusType, AUTOMATIC)                              Lin_RetTmp7;
  
  Lin_RetTmp7                                          = LIN_NOT_OK;
   
#if ( LIN_DEV_ERROR_DETECT == STD_ON )
  if (Lin_ChannelData[Channel].Lin_ModuleInit_Status == LIN_UNINIT  )
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_GETSTATUS_ID, LIN_E_UNINIT);	  											
  }
  /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason -  LDRA causing this problem."*/
  else if ( Channel >= Lin_TotalNumberOfChannels )
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_GETSTATUS_ID, LIN_E_INVALID_CHANNEL);	  											
  }
  /*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."*/
  else if ( Lin_SduPtr == (P2VAR(uint8 *, AUTOMATIC, LIN_APPL_VAR))NULL_PTR )
  {
    (void)Det_ReportError(LIN_MODULE_ID, (uint8)0x00U, LIN_GETSTATUS_ID, LIN_E_INVALID_POINTER);	  											
  }
  else
#endif
  {
	Lin_ChannelDataPtrTmp7                      = &Lin_ChannelData[Channel];

    Lin_RegisterStructPtrTmp7                   = (P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)) \
                                                   Lin_Data_Config[Channel].Lin_HardwareBaseAdress;

    if ((Lin_ChannelDataPtrTmp7->Lin_Drc == (Lin_FrameResponseType)LIN_SLAVE_RESPONSE) &&
	    (Lin_ChannelDataPtrTmp7->Lin_Status   == LIN_RX_OK))
       {
          *Lin_SduPtr                                = Lin_ChannelDataPtrTmp7->Lin_DataBuffer;
       }
    
    if ( Lin_ChannelDataPtrTmp7->Lin_State == Lin_OnTxAfterHeader )
    {
      /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_RegisterStructPtrTmp7 is already assigned a value "*/
	  /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
	  if((Lin_RegisterStructPtrTmp7->Lin_SCIFLR & Lin_TXEMPTY) != 0U)
		{
    	    Lin_ChannelDataPtrTmp7->Lin_Status    = LIN_TX_OK;
    	}     	
    }    
	/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
	/*SAFETYMCUSW 134 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
    if ((Lin_ChannelDataPtrTmp7->Lin_State == Lin_OnTxWakeup) &&
		/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
		/*SAFETYMCUSW 134 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
    	((Lin_RegisterStructPtrTmp7->Lin_SCIGCR2 & Lin_GENWU)  != 0U) &&
    	((Lin_RegisterStructPtrTmp7->Lin_SCIFLR & Lin_TXEMPTY) == Lin_TXEMPTY)
	   )
    {

    	Lin_RegisterStructPtrTmp7->Lin_SCIGCR1          &= (~Lin_SWnRESET);
    	Lin_RegisterStructPtrTmp7->Lin_SCIGCR1          |= Lin_SWnRESET;

    	Lin_ChannelDataPtrTmp7->Lin_State          = Lin_OnWake;
    }
    
    Lin_RetTmp7 = Lin_ChannelDataPtrTmp7->Lin_Status;
  }  
  return(Lin_RetTmp7);
}


#if (LIN_LOOPBACKTEST_ENABLE == STD_ON)
/**********************************************************************************************************************
 *  Lin_TestLoopBackModeEnable
 *  Description given in Lin.h
 *********************************************************************************************************************/
/* SourceId : LIN_SourceId_009 */
/* DesignId : LIN_DesignId_014 */
/* Requirements : AR_LIN_SR162 */
 FUNC(Std_ReturnType, LIN_CODE)  Lin_TestLoopBackModeEnable
(
VAR(uint8, AUTOMATIC)                                 Channel,
VAR(uint8, AUTOMATIC)                                 LoopBackMode
)
{
	P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)      Lin_RegisterStructPtrTmp8;
	VAR(Std_ReturnType, AUTOMATIC)                         Lin_RetTmp8;

    Lin_RetTmp8                                  = (Std_ReturnType)E_NOT_OK;
	/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason -  LDRA causing this problem."*/
    if((Channel < Lin_TotalNumberOfChannels) && (LoopBackMode < 2U))     
	{
		/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_Data_Config is already assigned a value "*/
		Lin_RegisterStructPtrTmp8                   = (P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)) \
													   Lin_Data_Config[Channel].Lin_HardwareBaseAdress;

		if(0U == LoopBackMode)
		{
			/* Enable Digital loopback */
			/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_RegisterStructPtrTmp8 is already assigned a value "*/
			Lin_RegisterStructPtrTmp8->Lin_IODFTCTRL    = Lin_EnableTestMode;
			Lin_RetTmp8 = (Std_ReturnType)E_OK;
		}
		else
		{
			/* Enable Analog loopback */
			/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_RegisterStructPtrTmp8 is already assigned a value "*/
			Lin_RegisterStructPtrTmp8->Lin_IODFTCTRL    = Lin_EnableTestMode;
			Lin_RegisterStructPtrTmp8->Lin_IODFTCTRL   |= Lin_EnableAnalogLoopback;
			Lin_RetTmp8 = (Std_ReturnType)E_OK;
		}		
	}
	return(Lin_RetTmp8);
}
/**********************************************************************************************************************
 *  Lin_TestLoopBackModeDisable
 *  Description given in Lin.h
 *********************************************************************************************************************/
/* SourceId : LIN_SourceId_009 */
/* DesignId : LIN_DesignId_015 */
/* Requirements : AR_LIN_SR162 */
 FUNC(Std_ReturnType, LIN_CODE)  Lin_TestLoopBackModeDisable
(
VAR(uint8, AUTOMATIC)                                 Channel
)
{
	P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)      Lin_RegisterStructPtrTmp9;
	VAR(Std_ReturnType, AUTOMATIC)                         Lin_RetTmp9;

    Lin_RetTmp9                                  = (Std_ReturnType)E_NOT_OK;
	/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason -  LDRA causing this problem."*/
	if(Channel < Lin_TotalNumberOfChannels)     
	{
		/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_Data_Config is already assigned a value "*/
		Lin_RegisterStructPtrTmp9                   = (P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)) \
													   Lin_Data_Config[Channel].Lin_HardwareBaseAdress;

		/* Disable loopback */
		/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_RegisterStructPtrTmp9 is already assigned a value "*/
		Lin_RegisterStructPtrTmp9->Lin_IODFTCTRL    = Lin_DisableTestMode;
		/* Disable Receive Mask */
		Lin_RegisterStructPtrTmp9->Lin_LINMASK         = Lin_MaskTXID;
		Lin_RetTmp9 = (Std_ReturnType)E_OK;
	}
	return(Lin_RetTmp9);
}

/**********************************************************************************************************************
 *  Lin_LoopBackSendFrame
 *  Description given in Lin.h
**********************************************************************************************************************/
/* SourceId : LIN_SourceId_009 */
/* DesignId : LIN_DesignId_016 */
/* Requirements : AR_LIN_SR162 */
FUNC(Std_ReturnType, LIN_CODE) Lin_LoopBackSendFrame
(
    VAR(uint8, AUTOMATIC)                                       Channel,
	/*SAFETYMCUSW 62D MR:16.7 <APPROVED> "Reason - Function defined as per the Autosar specification"*/
	P2VAR(Lin_PduType, AUTOMATIC, LIN_APPL_VAR)                 PduInfoPtr
)
{
  /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
  P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS) Lin_RegisterStructPtrTmp11 = NULL_PTR;
  VAR(Std_ReturnType, AUTOMATIC)                              Lin_RetTmp11;
  /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
  P2VAR(Lin_ChannelDataType, AUTOMATIC, LIN_VAR_NOINIT)  Lin_ChannelDataPtrTmp9 = NULL_PTR;
  
  Lin_RetTmp11                              = E_NOT_OK;
  
  /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason -  LDRA causing this problem."*/
  /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
  /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
  if((Channel < Lin_TotalNumberOfChannels) && (PduInfoPtr != (P2VAR(Lin_PduType, AUTOMATIC, LIN_APPL_VAR))NULL_PTR))
  {
	  Lin_ChannelDataPtrTmp9                          = &Lin_ChannelData[Channel];
	  /*SAFETYMCUSW 203S MR:11.5 <APPROVED> "Reason - To store the value of type Lin_RegisterStructType"*/
	  /*SAFETYMCUSW 95S MR: <APPROVED> "Reason -  To access pointer value of type Lin_RegisterStructType"*/
      Lin_RegisterStructPtrTmp11                       = (P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)) \
                                                         Lin_Data_Config[Channel].Lin_HardwareBaseAdress;
	  /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_RegisterStructPtrTmp11 is already assigned a value "*/	
      Lin_RegisterStructPtrTmp11->Lin_SCIGCR1          &= (~Lin_SWnRESET);

      if ( PduInfoPtr->Cs == (Lin_FrameCsModelType)LIN_ENHANCED_CS )
      {
        /* using enhanced checksum */
        Lin_RegisterStructPtrTmp11->Lin_SCIGCR1        |= Lin_CTYPE;
      }
      else
      {
        /* using classic checksum */
        Lin_RegisterStructPtrTmp11->Lin_SCIGCR1        &= (~Lin_CTYPE);
      }

      /* set DLC */
      Lin_RegisterStructPtrTmp11->Lin_SCIFORMAT         = (((uint32)PduInfoPtr->Dl-0x01U)<<16U);	  
      
	  Lin_ChannelDataPtrTmp9->Lin_Drc           = PduInfoPtr->Drc;     	  
	 
	  Lin_RegisterStructPtrTmp11->Lin_LINMASK         = (Lin_MaskRXID | Lin_MaskTXID);	 
	 
      Lin_RegisterStructPtrTmp11->Lin_SCIGCR1          |= Lin_SWnRESET;
	  
	  /* Wait till the SWnRESET bit is set */
	  do
	  {
	  
	  }
	  /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
	  while(((Lin_RegisterStructPtrTmp11->Lin_SCIGCR1 & Lin_SWnRESET) != Lin_SWnRESET));

      Lin_RegisterStructPtrTmp11->Lin_LINID.Lin_IDByte  = PduInfoPtr->Pid;
	  
      /*SAFETYMCUSW 94S MR:11.1 <APPROVED> "Reason - To access data value of SduPtr of type uint32"*/
	  /*SAFETYMCUSW 94 S MR:11.1, 11.2, 11.4 <APPROVED> "Reason - Casting is required here "*/
	  /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
      Lin_RegisterStructPtrTmp11->Lin_LINTD0            = *((P2VAR(uint32, AUTOMATIC, LIN_VAR_REGS))& \
	                                                     (PduInfoPtr->SduPtr[0U]));
	  /*SAFETYMCUSW 94S MR:11.1 <APPROVED> "Reason - To access data value of SduPtr of type uint32"*/
	  /*SAFETYMCUSW 94 S MR:11.1, 11.2, 11.4 <APPROVED> "Reason - Casting is required here "*/
	  /*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
      Lin_RegisterStructPtrTmp11->Lin_LINTD1            = *((P2VAR(uint32, AUTOMATIC, LIN_VAR_REGS))& \
	                                                      (PduInfoPtr->SduPtr[4U]));

      Lin_RetTmp11                                      = E_OK;	  
    }      
  return(Lin_RetTmp11); 
}
/**********************************************************************************************************************
 *  Lin_LoopBackDataTest
 *  Description given in Lin.h
**********************************************************************************************************************/
FUNC(Std_ReturnType, LIN_CODE) Lin_LoopBackDataTest
(
    VAR(uint8, AUTOMATIC)                                       Channel	
)
{
	P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS) Lin_RegisterStructPtrTmp12;
	VAR(Std_ReturnType, AUTOMATIC)                              Lin_RetTmp12;
	
	Lin_RetTmp12                              = E_NOT_OK;
	
	if(Channel < Lin_TotalNumberOfChannels)
	{
		/*SAFETYMCUSW 203S MR:11.5 <APPROVED> "Reason - To store the value of type Lin_RegisterStructType"*/
		/*SAFETYMCUSW 95S MR: <APPROVED> "Reason -  To access pointer value of type Lin_RegisterStructType"*/
		Lin_RegisterStructPtrTmp12                       = (P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)) \
															 Lin_Data_Config[Channel].Lin_HardwareBaseAdress;		
		
		/*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL pointer is defined as void pointer to zero."*/
		if(Lin_RegisterStructPtrTmp12 != NULL_PTR)
		{
			/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
			/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
			/*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
			if((Lin_RegisterStructPtrTmp12->Lin_LINTD0 == 
			   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
			   /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
			   Lin_RegisterStructPtrTmp12->Lin_LINRD0) &&			    
				/*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
				/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
			   (Lin_RegisterStructPtrTmp12->Lin_LINTD1 == 
			     /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
				 /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason -  volatile is required here."*/
				 Lin_RegisterStructPtrTmp12->Lin_LINRD1))
			{
				Lin_RetTmp12 = E_OK;
			}  
		}	
	}	
	return (Lin_RetTmp12);
}
#endif


#if(STD_ON == LIN_SAFETI_API)
/**********************************************************************************************************************
 *  Lin_ConfigRegReadBack
 *  Description given in Lin.h
 *********************************************************************************************************************/
/* SourceId : LIN_SourceId_010 */
/* DesignId : LIN_DesignId_017*/
/* Requirements : AR_LIN_SR163 */
 FUNC(Std_ReturnType, LIN_CODE) Lin_ConfigRegReadBack
(
		VAR(uint8, AUTOMATIC)                                       Channel
)
{

	P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)      Lin_RegisterStructPtrTmp10;
	VAR(Std_ReturnType, AUTOMATIC)                         Lin_RetTmp10;

    Lin_RetTmp10                                  = (Std_ReturnType)E_NOT_OK;
	/*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason -  LDRA causing this problem."*/
	if(Channel >= Lin_TotalNumberOfChannels) 
    {		
		
    }
	else
	{
		/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_Data_Config is already assigned a value "*/
		Lin_RegisterStructPtrTmp10                   = (P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)) \
													   Lin_Data_Config[Channel].Lin_HardwareBaseAdress;

		/* Read configuration registers value */
		/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_RegisterStructPtrTmp10 is already assigned a value "*/
		Lin_LinConfig.Lin_ReadBack_SCIGCR0 		= Lin_RegisterStructPtrTmp10->Lin_SCIGCR0;
		Lin_LinConfig.Lin_ReadBack_SCIGCR1 		= Lin_RegisterStructPtrTmp10->Lin_SCIGCR1;
		Lin_LinConfig.Lin_ReadBack_SCISETINT 	= Lin_RegisterStructPtrTmp10->Lin_SCISETINT;
		Lin_LinConfig.Lin_ReadBack_BRSR 		= Lin_RegisterStructPtrTmp10->Lin_BRSR;
		Lin_LinConfig.Lin_ReadBack_SCIPIO0 		= Lin_RegisterStructPtrTmp10->Lin_SCIPIO0;
		Lin_LinConfig.Lin_ReadBack_LINCOMP 		= Lin_RegisterStructPtrTmp10->Lin_LINCOMP;
		Lin_LinConfig.Lin_ReadBack_LINMASK 		= Lin_RegisterStructPtrTmp10->Lin_LINMASK;
		Lin_LinConfig.Lin_ReadBack_MBRSR 		= Lin_RegisterStructPtrTmp10->Lin_MBRSR;
		
		Lin_RetTmp10 = (Std_ReturnType)E_OK;
	}	
	return(Lin_RetTmp10);
}
#endif


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

#define LIN_START_SEC_CODE_ISR
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"
/**********************************************************************************************************************
 *  Lin_Interrupt
 *  Description given in Lin.h
 *********************************************************************************************************************/
/* SourceId : LIN_SourceId_011 */
/* DesignId : LIN_DesignId_018 */
/* Requirements : AR_LIN_SR11, AR_LIN_SR22, AR_LIN_SR31, AR_LIN_SR38, AR_LIN_SR53, AR_LIN_SR54, AR_LIN_SR56, 
                  AR_LIN_SR57, AR_LIN_SR61, AR_LIN_SR63, AR_LIN_SR143, AR_LIN_SR21, AR_LIN_SR170 */
/*SAFETYMCUSW 69 S MR:3.4 <APPROVED> "Reason - Pragma usage is required here to force ISR to ARM mode."*/
#pragma CODE_STATE(Lin_Interrupt, 32)
FUNC(void, LIN_CODE_ISR) Lin_Interrupt
(
  VAR(uint8, AUTOMATIC)                                       LinHwChannel
)
{
  VAR(uint8, AUTOMATIC)                                       ChannelTmp8; 

  volatile VAR(uint32, AUTOMATIC)                             Lin_SCIINTVECT0Tmp;
  volatile VAR(uint32, AUTOMATIC)                             Lin_FlagRegTmp;  
  VAR(uint32, AUTOMATIC)                                      FlagRegTmp;
  
  P2VAR(Lin_ChannelDataType, AUTOMATIC, LIN_VAR_NOINIT)       Lin_ChannelDataPtrTmp8;
  P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)      Lin_RegisterStructPtrTmp8;
 
  ChannelTmp8                                 = LinHwChannel;  

  Lin_ChannelDataPtrTmp8                      = &Lin_ChannelData[ChannelTmp8];

  /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_Data_Config is already assigned a value "*/
  Lin_RegisterStructPtrTmp8                   = (P2VAR(Lin_RegisterStructType, AUTOMATIC, LIN_VAR_REGS)) \
                                                   Lin_Data_Config[ChannelTmp8].Lin_HardwareBaseAdress;
  /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Lin_RegisterStructPtrTmp8 is already assigned a value "*/
  Lin_FlagRegTmp                   = Lin_RegisterStructPtrTmp8->Lin_SCIFLR;                      
  Lin_SCIINTVECT0Tmp               = Lin_RegisterStructPtrTmp8->Lin_SCIINTVECT0;/* Save interrupt vector */


  switch (Lin_SCIINTVECT0Tmp)
  {
	case Lin_IntVect_ID:
	
		FlagRegTmp = Lin_FlagRegTmp;    
		
		if((FlagRegTmp & Lin_TXID ) != 0U)
		{

		  if(Lin_RegisterStructPtrTmp8->Lin_LINID.Lin_IDByte == Lin_SleepCommand)
		  {
			Lin_ChannelDataPtrTmp8->Lin_State           = Lin_OnTxSleepModeFrameAfterHeader;
			Lin_ChannelDataPtrTmp8->Lin_Status          = LIN_TX_BUSY;
		  }
		  else
		  {
			Lin_ChannelDataPtrTmp8->Lin_State           = Lin_OnTxAfterHeader;
			Lin_ChannelDataPtrTmp8->Lin_Status          = LIN_TX_BUSY;
			#if (LIN_LOOPBACKTEST_ENABLE == STD_ON)
			Lin_ChannelDataPtrTmp8->Lin_State           = Lin_OnLoopback;
			#endif
		  }		  
		}
		else if((FlagRegTmp & Lin_RXID ) != 0U)
		{
		  Lin_ChannelDataPtrTmp8->Lin_State             = Lin_OnRxAfterHeader;
		  Lin_ChannelDataPtrTmp8->Lin_Status            = LIN_RX_BUSY;			
		} 
		else
		{
		  Lin_ChannelDataPtrTmp8->Lin_State             = Lin_OnS2SAfterHeader;
		  Lin_ChannelDataPtrTmp8->Lin_Status            = LIN_TX_OK;            	
		}
	break;
	
	case Lin_IntVect_NoInterrupt:
		Lin_ChannelDataPtrTmp8->Lin_State             = Lin_PhanthomError;
		Lin_ChannelDataPtrTmp8->Lin_Status            = LIN_NOT_OK;            	
	break;

	case Lin_IntVect_Wakeup:
		if ( Lin_ChannelDataPtrTmp8->Lin_State == Lin_OnSleep )
		{
			/* Ignore wakeup frames if wakeup support has been disabled */
			if ( Lin_Data_Config[ChannelTmp8].Lin_WakeupSupport == STD_ON )
			{
			  Lin_IrqWakeupEvent                    |= (uint8)(0x01U << ChannelTmp8);
				
			  /* Inform Ecu Manager about wakeup frame */
			  EcuM_CheckWakeup(Lin_Data_Config[ChannelTmp8].Lin_EcuMWakeupSource);
			}
		}

	break;  

	case Lin_IntVect_Receive:

		switch (Lin_ChannelDataPtrTmp8->Lin_State)
		{
		  #if (LIN_LOOPBACKTEST_ENABLE == STD_ON)
		  case Lin_OnLoopback:
		  #endif
		  case Lin_OnRxAfterHeader:
			/*SAFETYMCUSW 94 S MR:11.1, 11.2, 11.4 <APPROVED> "Reason - Casting is required here "*/
			/*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
			*((P2VAR(uint32, AUTOMATIC, LIN_VAR_NOINIT))&(Lin_ChannelDataPtrTmp8->Lin_DataBuffer[0U])) =  \
															Lin_RegisterStructPtrTmp8->Lin_LINRD0;
			/*SAFETYMCUSW 94 S MR:11.1, 11.2, 11.4 <APPROVED> "Reason - Casting is required here "*/
			/*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
			*((P2VAR(uint32, AUTOMATIC, LIN_VAR_NOINIT))&(Lin_ChannelDataPtrTmp8->Lin_DataBuffer[4U])) =  \
															 Lin_RegisterStructPtrTmp8->Lin_LINRD1;
			Lin_ChannelDataPtrTmp8->Lin_State             = Lin_OnWake;
			Lin_ChannelDataPtrTmp8->Lin_Status            = LIN_RX_OK;
		  break;

		  case Lin_OnTxSleepModeFrameAfterHeader:			
			/*SAFETYMCUSW 94 S MR:11.1, 11.2, 11.4 <APPROVED> "Reason - Casting is required here "*/
			/*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
			*((P2VAR(uint32, AUTOMATIC, LIN_VAR_NOINIT))&(Lin_ChannelDataPtrTmp8->Lin_DataBuffer[0U])) =  \
															Lin_RegisterStructPtrTmp8->Lin_LINRD0;
			/*SAFETYMCUSW 94 S MR:11.1, 11.2, 11.4 <APPROVED> "Reason - Casting is required here "*/
			/*SAFETYMCUSW 95 S MR:11.1,11.4 <APPROVED> "Reason -  Casting is required here."*/
			*((P2VAR(uint32, AUTOMATIC, LIN_VAR_NOINIT))&(Lin_ChannelDataPtrTmp8->Lin_DataBuffer[4U])) =  \
															 Lin_RegisterStructPtrTmp8->Lin_LINRD1;
            if(Lin_ChannelDataPtrTmp8->Lin_DataBuffer[0] == 0x00U)
            {			
				(void)Lin_GoToSleepInternal(ChannelTmp8);
			}	
			else 
            { 
				Lin_ChannelDataPtrTmp8->Lin_Status = LIN_TX_OK; 
				Lin_ChannelDataPtrTmp8->Lin_State = Lin_OnTxAfterHeader; 
		    } 				
		  break;
		
		  default:
			Lin_ChannelDataPtrTmp8->Lin_State             = Lin_OnWake;
		  break;
		}
		break;
			
	case Lin_IntVect_Transmit:
	break;
	
	case Lin_IntVect_BreakDetect:
	break;
	
	case Lin_IntVect_ParityError:
	     Lin_ChannelDataPtrTmp8->Lin_Status             = LIN_TX_HEADER_ERROR;
		 Lin_ChannelDataPtrTmp8->Lin_State              = Lin_OnWake;         
		 #if ((LIN_CALL_USERCALLOUT == STD_OFF)  && (LIN_E_PARITY != LIN_DEM_NO_EVENT))
		 Dem_ReportErrorStatus((Dem_EventIdType)LIN_E_PARITY, DEM_EVENT_STATUS_FAILED);
		 #elif(LIN_CALL_USERCALLOUT == STD_ON)
		 USERCALLOUT(LIN_ERROR_PARITY);
		 #endif		 
	break;
	
	case Lin_IntVect_IncSynchFieldError:
		 Lin_ChannelDataPtrTmp8->Lin_Status             = LIN_TX_HEADER_ERROR;
		 Lin_ChannelDataPtrTmp8->Lin_State              = Lin_OnWake;
		 #if ((LIN_CALL_USERCALLOUT == STD_OFF)  && (LIN_E_SYNCFIELD != LIN_DEM_NO_EVENT))
		 Dem_ReportErrorStatus((Dem_EventIdType)LIN_E_SYNCFIELD, DEM_EVENT_STATUS_FAILED); 	 
		 #elif(LIN_CALL_USERCALLOUT == STD_ON)
		 USERCALLOUT(LIN_ERROR_SYNCFIELD);
		 #endif         
	break;
	
	case Lin_IntVect_FrameError:
		 if(Lin_ChannelDataPtrTmp8->Lin_State == Lin_OnRxAfterHeader)
		 {
			Lin_ChannelDataPtrTmp8->Lin_State           = Lin_OnWake;
			Lin_ChannelDataPtrTmp8->Lin_Status          = LIN_RX_ERROR;
		 }
		 else if(Lin_ChannelDataPtrTmp8->Lin_State == Lin_OnTxAfterHeader)
		 {
			Lin_ChannelDataPtrTmp8->Lin_State           = Lin_OnWake;
			Lin_ChannelDataPtrTmp8->Lin_Status          = LIN_TX_ERROR;
		 }
		 else if((Lin_ChannelDataPtrTmp8->Lin_State == Lin_OnTxSleepModeFrameAfterHeader) || 
	  		   (Lin_ChannelDataPtrTmp8->Lin_State == Lin_OnTxSleepModeFrame))
		{
			(void)Lin_GoToSleepInternal(ChannelTmp8);
		}
		else
		{
			Lin_ChannelDataPtrTmp8->Lin_State           = Lin_OnWake;
			Lin_ChannelDataPtrTmp8->Lin_Status          = LIN_TX_HEADER_ERROR;
		}	
	    #if ((LIN_CALL_USERCALLOUT == STD_OFF)  && (LIN_E_FRM != LIN_DEM_NO_EVENT))
		Dem_ReportErrorStatus((Dem_EventIdType)LIN_E_FRM, DEM_EVENT_STATUS_FAILED); 	 
		#elif(LIN_CALL_USERCALLOUT == STD_ON)
		USERCALLOUT(LIN_ERROR_FRM);
		#endif		
    break;		 
	case Lin_IntVect_BitError:
		 if(Lin_ChannelDataPtrTmp8->Lin_State == Lin_OnRxAfterHeader)
		 {
			Lin_ChannelDataPtrTmp8->Lin_State           = Lin_OnWake;
			Lin_ChannelDataPtrTmp8->Lin_Status          = LIN_RX_ERROR;
		 }
		 else if(Lin_ChannelDataPtrTmp8->Lin_State == Lin_OnTxAfterHeader)
		 {
			Lin_ChannelDataPtrTmp8->Lin_State           = Lin_OnWake;
			Lin_ChannelDataPtrTmp8->Lin_Status          = LIN_TX_ERROR;
		 }
		 else if((Lin_ChannelDataPtrTmp8->Lin_State == Lin_OnTxSleepModeFrameAfterHeader) || 
	  		   (Lin_ChannelDataPtrTmp8->Lin_State == Lin_OnTxSleepModeFrame))
		 {
			(void)Lin_GoToSleepInternal(ChannelTmp8);
		 }
		 else
		 {
			Lin_ChannelDataPtrTmp8->Lin_State           = Lin_OnWake;
			Lin_ChannelDataPtrTmp8->Lin_Status          = LIN_TX_HEADER_ERROR;
		 }	
	     #if ((LIN_CALL_USERCALLOUT == STD_OFF)  && (LIN_E_BIT != LIN_DEM_NO_EVENT))
		 Dem_ReportErrorStatus((Dem_EventIdType)LIN_E_BIT, DEM_EVENT_STATUS_FAILED); 	
		 #elif(LIN_CALL_USERCALLOUT == STD_ON)
		 USERCALLOUT(LIN_ERROR_BIT);
		 #endif
	break;
		 
	case Lin_IntVect_PhysicalBusError:				   
	     if(Lin_ChannelDataPtrTmp8->Lin_State == Lin_OnRxAfterHeader)
	     {
			Lin_ChannelDataPtrTmp8->Lin_State           = Lin_OnWake;
			Lin_ChannelDataPtrTmp8->Lin_Status          = LIN_RX_ERROR;
	     }
	     else if(Lin_ChannelDataPtrTmp8->Lin_State == Lin_OnTxAfterHeader)
	     {
			Lin_ChannelDataPtrTmp8->Lin_State           = Lin_OnWake;
			Lin_ChannelDataPtrTmp8->Lin_Status          = LIN_TX_ERROR;
	     }
	     else if((Lin_ChannelDataPtrTmp8->Lin_State == Lin_OnTxSleepModeFrameAfterHeader) || 
	  		   (Lin_ChannelDataPtrTmp8->Lin_State == Lin_OnTxSleepModeFrame))
		 {
			(void)Lin_GoToSleepInternal(ChannelTmp8);
		 }
		 else
		 {
			Lin_ChannelDataPtrTmp8->Lin_State           = Lin_OnWake;
			Lin_ChannelDataPtrTmp8->Lin_Status          = LIN_TX_HEADER_ERROR;
		 }
		 #if ((LIN_CALL_USERCALLOUT == STD_OFF)  && (LIN_E_PHYBUS != LIN_DEM_NO_EVENT))
		 Dem_ReportErrorStatus((Dem_EventIdType)LIN_E_PHYBUS, DEM_EVENT_STATUS_FAILED); 	
		 #elif(LIN_CALL_USERCALLOUT == STD_ON)
		 USERCALLOUT(LIN_ERROR_PHYBUS);
		 #endif		 
	break;	

	case Lin_IntVect_OverrunError:
		 Lin_ChannelDataPtrTmp8->Lin_State              = Lin_OnWake;
		 Lin_ChannelDataPtrTmp8->Lin_Status             = LIN_RX_ERROR;
		 #if ((LIN_CALL_USERCALLOUT == STD_OFF)  && (LIN_E_OVRRUN != LIN_DEM_NO_EVENT))
		 Dem_ReportErrorStatus((Dem_EventIdType)LIN_E_OVRRUN, DEM_EVENT_STATUS_FAILED); 	
		 #elif (LIN_CALL_USERCALLOUT == STD_ON)
		 USERCALLOUT(LIN_ERROR_OVRRUN);
		 #endif		 
	break;
	
	case Lin_IntVect_ChecksumError:
		 Lin_ChannelDataPtrTmp8->Lin_State              = Lin_OnWake;
		 Lin_ChannelDataPtrTmp8->Lin_Status             = LIN_RX_ERROR;
		 #if ((LIN_CALL_USERCALLOUT == STD_OFF)  && (LIN_E_CHKSUM != LIN_DEM_NO_EVENT))
		 Dem_ReportErrorStatus((Dem_EventIdType)LIN_E_CHKSUM, DEM_EVENT_STATUS_FAILED);
		 #elif (LIN_CALL_USERCALLOUT == STD_ON)
		 USERCALLOUT(LIN_ERROR_CHKSUM);
		 #endif
	break;        
	
	case Lin_IntVect_NoResponseError:
		 Lin_ChannelDataPtrTmp8->Lin_State              = Lin_OnWake;
		 Lin_ChannelDataPtrTmp8->Lin_Status             = LIN_RX_NO_RESPONSE;
		 #if ((LIN_CALL_USERCALLOUT == STD_OFF)  && (LIN_E_NORESPONSE != LIN_DEM_NO_EVENT))
		 Dem_ReportErrorStatus((Dem_EventIdType)LIN_E_NORESPONSE, DEM_EVENT_STATUS_FAILED);
		 #elif (LIN_CALL_USERCALLOUT == STD_ON)
		 USERCALLOUT(LIN_ERROR_NORESPONSE);
		 #endif
	break;
	
	case Lin_IntVect_TimeoutAfterWakeup:
	case Lin_IntVect_TimeoutAfter3Wakeup:
		/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  volatile is required here."*/
         if((Lin_RegisterStructPtrTmp8->Lin_SCIGCR2 & Lin_POWERDOWN) == Lin_POWERDOWN)
         {
             Lin_ChannelDataPtrTmp8->Lin_State           = Lin_OnSleep;
             Lin_ChannelDataPtrTmp8->Lin_Status          = LIN_CH_SLEEP;
         }
         else
         {
             Lin_ChannelDataPtrTmp8->Lin_State              = Lin_OnWake;
             Lin_ChannelDataPtrTmp8->Lin_Status             = LIN_RX_NO_RESPONSE;
         }
	break;

	case Lin_IntVect_TimeoutBusIdle:
	     Lin_ChannelDataPtrTmp8->Lin_State              = Lin_Timeout;		 
		 Dem_ReportErrorStatus((Dem_EventIdType)LIN_E_TIMEOUT, DEM_EVENT_STATUS_FAILED);
	break;
	default:
	break;    
  }
}
#define LIN_STOP_SEC_CODE_ISR
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format to use for specifying memorysections."*/
#include "MemMap.h"

/**********************************************************************************************************************
 *  END OF FILE: Lin.c
 *********************************************************************************************************************/
