/**********************************************************************************************************************
 *  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:  Pwm.c
 *    Component:  Tms570_AutosarPwmDriver
 *       Module:  PwmDriver
 *    Generator:  -
 *
 *  Description: This component provides services for initialization and control of the microcontroller internal
 *                PWM unit (pulse width modulation). The PWM module generates pulses with variable pulse width.
 *                It allows the selection of the duty cycle and the signal period time.
 *********************************************************************************************************************/

/**********************************************************************************************************************
 *---------------------------------------------------------------------------------------------------------------------
 * Author:  Vineeth Thomas Alex
 *---------------------------------------------------------------------------------------------------------------------
 * Revision History
 *---------------------------------------------------------------------------------------------------------------------
 * Version     Date           Author                   Change ID          Description
 *---------------------------------------------------------------------------------------------------------------------
 * 02.21.00    30Sep2014     Vineeth Thomas Alex      SDOCM00113122      Initial version adapted from TMS570LS3137
 *                                                     SDOCM00108292      Bug fixes for Pwm_SetOutputToIdle() reset
 * 02.21.01    23Aug2016     Vishwanath Reddy         SDOCM00122620      Vresion info updated. 
 * 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 "Pwm.h"
#include "Pwm_Irq.h"
#include "Pwm_Het.h"
#include "SchM_Pwm.h"
#if ( STD_ON == PWM_DEV_ERROR_DETECT )
	/*File containing error-hook function*/
    #include "Det.h"
#endif
/**********************************************************************************************************************
 *  VERSION CHECK
 *********************************************************************************************************************/
#define PWM_SW_C_MAJOR_VERSION               (5U)
#define PWM_SW_C_MINOR_VERSION               (30U)
#define PWM_SW_C_PATCH_VERSION               (0U)
 
 /* SourceId : PWM_SourceId_011 */
/* DesignId : PWM_DesignId_10  */
/* Requirements : AR_PWM_SR22 */
#if (  (PWM_AR_RELEASE_MAJOR_VERSION    != (0x04U)) \
    || (PWM_AR_RELEASE_MINOR_VERSION    != (0x00U)) \
    || (PWM_AR_RELEASE_REVISION_VERSION != (0x03U)) )
  #error "Pwm: AUTOSAR Version Numbers of Pwm are different"
#endif

#if (  (PWM_SW_MAJOR_VERSION != PWM_SW_C_MAJOR_VERSION) \
    || (PWM_SW_MINOR_VERSION != PWM_SW_C_MINOR_VERSION))
    #error "Version numbers of Pwm.c and Pwm.h are inconsistent!"

#endif

#if(   (PWM_CFG_MAJOR_VERSION != PWM_SW_C_MAJOR_VERSION) \
    || (PWM_CFG_MINOR_VERSION != PWM_SW_C_MINOR_VERSION))
    #error "Version numbers of Pwm.c and Pwm_Cfg.h are inconsistent!"
#endif

#if(   (PWM_IRQ_MAJOR_VERSION != PWM_SW_C_MAJOR_VERSION) \
    || (PWM_IRQ_MINOR_VERSION != PWM_SW_C_MINOR_VERSION))
    #error "Version numbers of Pwm.c and Pwm_Irq.h are inconsistent!"
#endif

/**********************************************************************************************************************
 *  LOCAL FUNCTION MACROS
 *********************************************************************************************************************/

/* SourceId : PWM_SourceId_008 */
/* DesignId : PWM_DesignId_08  */
/* Requirements : AR_PWM_SR18 */
#if ( STD_ON == PWM_DEV_ERROR_DETECT )
	#define Pwm_Errorhook(PWM_FunctionId,PWM_ErrorCode) Det_ReportError((PWM_MODULE_ID),(0U),(PWM_FunctionId),(PWM_ErrorCode))
#else /* STD_ON == PWM_DEV_ERROR_DETECT */
    #define Pwm_Errorhook(PWM_FunctionId, PWM_ErrorCode)
#endif /* STD_ON == PWM_DEV_ERROR_DETECT */

#define Pwm_GlobalSuspend() /*<PWM_GLOBAL_SUSPEND/>*/ SchM_Enter_Pwm_PWM_EXCLUSIVE_AREA_0()
#define Pwm_GlobalRestore() /*<PWM_GLOBAL_RESTORE/>*/ SchM_Exit_Pwm_PWM_EXCLUSIVE_AREA_0()


/*********************************************************************************************************************
 *  LOCAL DATA PROTOTYPES
 *********************************************************************************************************************/
/*---- Internal Module Global Variables ------------------------------------*/

#if ( STD_ON == PWM_DEV_ERROR_DETECT )
/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#define PWM_START_SEC_VAR_INIT_8
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#include "MemMap.h"

   /* global state of the pwm driver */
   static VAR(uint8, PWM_VAR) Pwm_Status_u8 = PWM_STATUS_UNINIT;

/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#define PWM_STOP_SEC_VAR_INIT_8
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#include "MemMap.h"
#endif /*(STD_ON == PWM_NOTIFICATION_SUPPORTED)*/

#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#define PWM_START_SEC_VAR_NO_INIT_8
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#include "MemMap.h"

   static VAR(uint8, PWM_VAR) Pwm_NotifyActivationState_au8[PWM_CHANNEL_MAX];

/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#define PWM_STOP_SEC_VAR_NO_INIT_8
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#include "MemMap.h"
#endif /*(STD_ON == PWM_NOTIFICATION_SUPPORTED)*/

/* Non-initialized variables */
/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#define PWM_START_SEC_VAR_NO_INIT_UNSPECIFIED
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#include "MemMap.h"

/* reference to the current global runtime configuration */
static P2CONST(Pwm_ConfigType, PWM_VAR, PWM_PBCFG) Pwm_CurrentConfig_pt;


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

/**********************************************************************************************************************
 *  LOCAL FUNCTION PROTOTYPES
 *********************************************************************************************************************/

/* Code section */
/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#define PWM_START_SEC_CODE
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#include "MemMap.h"

static FUNC(void, PWM_CODE) Pwm_CodeLoadInit(void);
#if ( STD_ON == PWM_DE_INIT_API )
   static FUNC(void, PWM_CODE) Pwm_SetRegDeInit(void);
#endif
#if (STD_ON == PWM_SET_DUTY_CYCLE_API)
   static FUNC(void, PWM_CODE) Pwm_HetSetDutyCycle (Pwm_ChannelType ChannelNumber, \
                                    uint16 DutyCycle, uint8 Het_ChannelOffset, P2VAR(Het_Pwm_InstructionType, PWM_VAR,\
                                           HET_RAM) HetRam, P2VAR(Pwm_HetRegisterType, PWM_VAR, MSR_REGSPACE) HetReg );
#endif
#if (STD_ON == PWM_SET_PERIOD_AND_DUTY_API)
   static FUNC(void, PWM_CODE) Pwm_HetSetPeriodAndDuty (Pwm_ChannelType ChannelNumber,  Pwm_PeriodType  Period,
                                    uint16 DutyCycle, uint8 Het_ChannelOffset, P2VAR(Het_Pwm_InstructionType, PWM_VAR,\
               		                       HET_RAM) HetRam, P2VAR(Pwm_HetRegisterType, PWM_VAR, MSR_REGSPACE) HetReg );
#endif
#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
   static FUNC(void, PWM_CODE) Pwm_HetEnableNotification (Pwm_ChannelType ChannelNumber, Pwm_EdgeNotificationType   \
		             Notification, uint8 Het_ChannelOffset, P2VAR(Het_Pwm_InstructionType, PWM_VAR, HET_RAM) HetRam, \
		                                                    P2VAR(Pwm_HetRegisterType, PWM_VAR, MSR_REGSPACE) HetReg );
#endif
#if ((STD_ON == PWM_SET_DUTY_CYCLE_API) || (STD_ON == PWM_SET_PERIOD_AND_DUTY_API) || \
   (STD_ON == PWM_SET_OUTPUT_TO_IDLE_API) || (STD_ON == PWM_NOTIFICATION_SUPPORTED))
   static FUNC(void, PWM_CODE) Pwm_UpdateFlag(Pwm_HetType* PwmHetFlagPtr, uint8* Het1_ChannelOffsetPtr, \
      uint8* Het2_ChannelOffsetPtr, Pwm_ChannelType ChannelNumber);
#endif
#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
   static FUNC(Pwm_ChannelType, PWM_CODE) Pwm_UpdateChannelNumber(Pwm_HetType PwmHet, uint32 Het_ChannelOffset);
#endif
/**********************************************************************************************************************
 * Function Name : Pwm_Init
 *********************************************************************************************************************/
/*  \Description: Service for PWM initialization; initializes internal variables
 *               and the PWM unit of the microcontroller.
 *  \param[in]:  Pwm_ConfigType* ConfigPtr - configuration structure for initialising the module.
 *  \return:     None
 *  \pre:        -Input parameter must not be NULL.
 *               -Call of service must not interrupt running operation
 *               -Module must be in state uninitalized before calling
 *  \context:    Called by upper layer.
 *  \note:       After initialization, all channels are started according
                 to their configuration's default values.
 *********************************************************************************************************************/
   /* SourceId : PWM_SourceId_014 */
   /* DesignId : PWM_DesignId_14  */
   /* Requirements : AR_PWM_SR34, AR_PWM_SR35, AR_PWM_SR36, AR_PWM_SR37, AR_PWM_SR38 */
FUNC(void, PWM_CODE) Pwm_Init ( P2CONST(Pwm_ConfigType, AUTOMATIC, PWM_PBCFG) ConfigPtr )
{
   /* ################### Begin dev error checks ######################### */

   /* check if configuration pointer is not NULL. if it is, report error
    * PWM_E_PARAM_CONFIG and return immediately
    */
#if ( STD_ON == PWM_DEV_ERROR_DETECT )
   /* SourceId : PWM_SourceId_031 */
   /* DesignId : PWM_DesignId_14  */
   /* Requirements : AR_PWM_SR7, AR_PWM_SR40 */
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL_PTR comes from Compiler.h" */
   if ( NULL_PTR == ConfigPtr )
   {
      /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
      Pwm_Errorhook( PWM_SID_INIT, PWM_E_PARAM_CONFIG );
   }


   /* SourceId : PWM_SourceId_030 */
   /* DesignId : PWM_DesignId_14  */
   /* Requirements : AR_PWM_SR11 */
   else if ( PWM_STATUS_INIT == Pwm_Status_u8 )
   {
      /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error ret value not required." */
      Pwm_Errorhook( PWM_SID_INIT, PWM_E_ALREADY_INITIALIZED );
   }

   else
#endif /* ( STD_ON == PWM_DEV_ERROR_DETECT ) */

   {
	  /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - ConfigPtr is checked for NULL" */
      Pwm_CurrentConfig_pt = ConfigPtr;

	 Pwm_CodeLoadInit();

   }
} /* void Pwm_Init( ... ) */

/**********************************************************************************************************************
 * Function Name : _Pwm_InitCodeLoad
 *********************************************************************************************************************/
/*  \Description: Service for PWM initialization; loads the code for NHET
 *  \param[in]:  -
 *  \return:     -
 *  \pre:        -
 *  \context:    Should be called from Pwm_Init only.
 *  \note:       -
 *********************************************************************************************************************/
static FUNC(void, PWM_CODE) Pwm_CodeLoadInit(void)
{
   uint8 Pwm_Noofchannels = 0U;
   Pwm_HetType Pwm_HetFlag = HETCLR;
   uint8 Count = 0U;
#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
   uint8 LoopCnt_u32;
#endif

   /*Het1 Ram & Register Base address will already be configured*/

#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
   /* Disable Interrupts globally */
   /*SAFETYMCUSW 134 S MR:21.1 <APPROVED> "Reason - To Clear Het1 Irq of type volatile" */
   PWM_HET1_IRQ_CLEAR = PWM_HET_IRQ_MASK;
   /*SAFETYMCUSW 134 S MR:21.1 <APPROVED> "Reason - To Clear Het2 Irq of type volatile" */
   PWM_HET2_IRQ_CLEAR = PWM_HET_IRQ_MASK;
#endif /*(STD_ON == PWM_NOTIFICATION_SUPPORTED)*/

   /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - It is checked for NULL in Pwm_Init(..)" */
   Pwm_Noofchannels =  Pwm_CurrentConfig_pt->NumberOfChannels_u8;
   Pwm_HetFlag = HETCLR;

   /*Check if Het1 Channels are configured */
   for(Count = 0U;Count < Pwm_Noofchannels;Count++)
   {
      if(Pwm_CurrentConfig_pt->ChannelConfig_at[Count].Het_t == HET1)
      {
         Pwm_HetFlag = HET1;
         break;
      }
   }
   if( HET1 == Pwm_HetFlag )
   {
      Pwm_HetFlag = HETCLR;
      /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Since PWM_HET1_RAM_ADDR is constant." */
      /*SAFETYMCUSW 344 S MR:11.5 <APPROVED> "Reason - Since PWM_HET1_RAM_ADDR is constant " */
      /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason - To calculate absolute
        address.Function takes uint32 as argument." */
      /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason - To calculate absolute
        address.Function takes uint32 as argument." */
      Pwm_GlobalSuspend();
      Pwm_Het_Init(Pwm_CurrentConfig_pt->Pwm_Het1Program_at, \
                 ((uint32) PWM_HET1_RAM_ADDR) - ((uint32)(0x300U)), (uint32) PWM_HET1_REG_ADDR);
      Pwm_GlobalRestore();
   }
   Pwm_HetFlag = HETCLR;
   /*Check if Het2 Channels are configured */
   for(Count = 0U;Count < Pwm_Noofchannels;Count++)
   {
      if(Pwm_CurrentConfig_pt->ChannelConfig_at[Count].Het_t == HET2)
      {
         Pwm_HetFlag = HET2;
         break;
      }
   }
   if( HET2 == Pwm_HetFlag )
   {
      Pwm_HetFlag = HETCLR;
      /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Since PWM_HET2_RAM_ADDR is constant." */
      /*SAFETYMCUSW 344 S MR:11.5 <APPROVED> "Reason - Since PWM_HET1_RAM_ADDR is constant " */
      /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason - To calculate absolute
        address.Function takes uint32 as argument." */
      /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason - To calculate absolute
        address.Function takes uint32 as argument." */
      Pwm_GlobalSuspend();
      Pwm_Het_Init(Pwm_CurrentConfig_pt->Pwm_Het2Program_at, \
                 ((uint32) PWM_HET2_RAM_ADDR) - ((uint32)(0x300U)), (uint32) PWM_HET2_REG_ADDR);
      Pwm_GlobalRestore();
   }
#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
	  /*Reset the module global variable which stores the current Notification status*/
	  for( LoopCnt_u32 = 0U; LoopCnt_u32 < Pwm_CurrentConfig_pt->NumberOfChannels_u8; LoopCnt_u32++ )
	  {
		 Pwm_NotifyActivationState_au8[LoopCnt_u32] = PWM_NO_EDGES;
	  }
#endif /*(STD_ON == PWM_NOTIFICATION_SUPPORTED)*/

#if ( STD_ON == PWM_DEV_ERROR_DETECT )
      Pwm_Status_u8 = PWM_STATUS_INIT;
#endif
} /* void Pwm_CodeLoadInit() */

#if ( STD_ON == PWM_DE_INIT_API )
/**********************************************************************************************************************
 * Function Name : Pwm_DeInit
 *********************************************************************************************************************/
/*  \Description:Service for PWM de-initialization.
 *               After deinit output states should be in idle level (it is configurable whether reset state is restored
 *               or if channel output states are really set to idle)
 *  \param[in]:  None
 *  \return:     None
 *  \pre:        The module must be initialized before calling this service.
 *********************************************************************************************************************/
/* SourceId : PWM_SourceId_015 */
/* DesignId : PWM_DesignId_15  */
/* Requirements : AR_PWM_SR44, AR_PWM_SR45, AR_PWM_SR46, AR_PWM_SR47, AR_PWM_SR48 */
FUNC(void, PWM_CODE) Pwm_DeInit( void )
{
   uint8 LoopCnt_u32 = 0U;
   Pwm_HetType Pwm_HetFlag = HETCLR;
   uint8 Pwm_Noofchannels = 0U;

   /* ################### Begin dev error checks ######################### */

   /* check if the pwm driver has been initialized. if it is not, report
    * error PWM_E_UNINIT and return immediately.
    */
#if ( STD_ON == PWM_DEV_ERROR_DETECT )
   /* SourceId : PWM_SourceId_039 */
   /* DesignId : PWM_DesignId_15  */
   /* Requirements : AR_PWM_SR8, AR_PWM_SR94 */
   if ( PWM_STATUS_INIT != Pwm_Status_u8 )
   {
      /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
      Pwm_Errorhook( PWM_SID_DE_INIT, PWM_E_UNINIT );
   }
   else
#endif /* ( STD_ON == PWM_DEV_ERROR_DETECT ) */

   {
      Pwm_Noofchannels =  Pwm_CurrentConfig_pt->NumberOfChannels_u8;

      /*Check if Het1 Channels are configured */
      for(LoopCnt_u32 = 0U;LoopCnt_u32 < Pwm_Noofchannels;LoopCnt_u32++)
      {
         if(Pwm_CurrentConfig_pt->ChannelConfig_at[LoopCnt_u32].Het_t == HET1)
         {
            Pwm_HetFlag = HET1;
            break;
         }
      }
      if( HET1 == Pwm_HetFlag )
      {
         Pwm_HetFlag = HETCLR;
         Pwm_GlobalSuspend();
         /*SAFETYMCUSW 344 S MR:11.5 <APPROVED> "Reason - Since PWM_HET1_RAM_ADDR is constant " */
         /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason - RamBaseAddress is of type integer" */
         /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason - To calculate absolute
           address.Function takes uint32 as argument." */
         Pwm_Het_DeInit((uint32)PWM_HET1_RAM_ADDR - ((uint32)(0x300U)), (uint32) PWM_HET1_REG_ADDR);
         Pwm_GlobalRestore();
#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
          /* Disable Interrupts globally */
          /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - To mask Het1 Irq bits" */
          PWM_HET1_IRQ_CLEAR = PWM_HET_IRQ_MASK;
#endif /*(STD_ON == PWM_NOTIFICATION_SUPPORTED)*/
      }
      /*Check if Het2 Channels are configured */
      for(LoopCnt_u32 = 0U;LoopCnt_u32 < Pwm_Noofchannels;LoopCnt_u32++)
      {
         if(Pwm_CurrentConfig_pt->ChannelConfig_at[LoopCnt_u32].Het_t == HET2)
         {
            Pwm_HetFlag = HET2;
            break;
         }
      }
      if( HET2 == Pwm_HetFlag )
      {
         Pwm_GlobalSuspend();
         /*SAFETYMCUSW 344 S MR:11.5 <APPROVED> "Reason - Since PWM_HET1_RAM_ADDR is constant " */
         /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason - RamBaseAddress is of type integer" */
         /*SAFETYMCUSW 439 S MR:11.3 <APPROVED> "Reason - To calculate absolute
           address.Function takes uint32 as argument." */
         Pwm_Het_DeInit((uint32)PWM_HET2_RAM_ADDR - ((uint32)(0x300U)), (uint32) PWM_HET2_REG_ADDR);
         Pwm_GlobalRestore();
#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
         /* Disable Interrupts globally */
         /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - To mask the Het2 Irq bits" */
         PWM_HET2_IRQ_CLEAR = PWM_HET_IRQ_MASK;
#endif /*(STD_ON == PWM_NOTIFICATION_SUPPORTED)*/
      }
   /* Perform register settings required for de-initialization*/
   Pwm_SetRegDeInit();

#if ( STD_ON == PWM_DEV_ERROR_DETECT )
   Pwm_Status_u8 = PWM_STATUS_UNINIT;
#endif
   }
} /* void Pwm_DeInit( ... ) */

/**********************************************************************************************************************
 * Function Name : Pwm_SetRegDeInit
 *********************************************************************************************************************/
/*  \Description: Service for PWM de-initialization; Does the register setting for de-initialization
 *  \param[in]:   None
 *  \return:      None
 *  \context:     Must be called from Pwm_DeInit only.
 *********************************************************************************************************************/
static FUNC(void, PWM_CODE) Pwm_SetRegDeInit( void)
{
   uint8 LoopCnt_u32 = 0U;
   uint32 Het1SetRegisterContent_u32 = 0U;
   uint32 Het1ClearRegisterContent_u32 = 0U;
   uint32 Het2SetRegisterContent_u32 = 0U;
   uint32 Het2ClearRegisterContent_u32 = 0U;

   for( LoopCnt_u32 = 0U; LoopCnt_u32 < Pwm_CurrentConfig_pt->NumberOfChannels_u8; LoopCnt_u32++ )
   {
      if(Pwm_CurrentConfig_pt->ChannelConfig_at[LoopCnt_u32].Het_t == HET1)
      {
         if(Pwm_CurrentConfig_pt->ChannelConfig_at[LoopCnt_u32].IdleState_t == PWM_HIGH )
         {
            Het1SetRegisterContent_u32 |= ((uint32)(1U) << \
               (Pwm_CurrentConfig_pt->ChannelConfig_at[LoopCnt_u32].OutputPin_u8));
         }
         else
         {
            Het1ClearRegisterContent_u32 |= ((uint32)(1U) << \
               (Pwm_CurrentConfig_pt->ChannelConfig_at[LoopCnt_u32].OutputPin_u8));
         }
      }
      else if(Pwm_CurrentConfig_pt->ChannelConfig_at[LoopCnt_u32].Het_t == HET2)
      {
         if(Pwm_CurrentConfig_pt->ChannelConfig_at[LoopCnt_u32].IdleState_t == PWM_HIGH )
         {
            Het2SetRegisterContent_u32 |= ((uint32)(1U) << \
               (Pwm_CurrentConfig_pt->ChannelConfig_at[LoopCnt_u32].OutputPin_u8));
         }
         else
         {
            Het2ClearRegisterContent_u32 |= ((uint32)(1U) << \
               (Pwm_CurrentConfig_pt->ChannelConfig_at[LoopCnt_u32].OutputPin_u8));
         }
      }
      else
      {
         /*Nothing*/
      }
   }

   Pwm_GlobalSuspend();

   /* Set the Pwm output pins to configured Idle State */
   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - To store Het1ClearRegisterContent_u32 content" */
   PWM_HET1_DATA_CLEAR = Het1ClearRegisterContent_u32;
   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - To Store Het1SetRegisterContent_u32 content" */
   PWM_HET1_DATA_SET = Het1SetRegisterContent_u32;
   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - To store Het2ClearRegisterContent_u32 content" */
   PWM_HET2_DATA_CLEAR = Het2ClearRegisterContent_u32;
   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - To store Het2SetRegisterContent_u32 content" */
   PWM_HET2_DATA_SET = Het2SetRegisterContent_u32;
   Pwm_GlobalRestore();

} /*void Pwm_SetRegDeInit()*/
#endif /*( STD_ON == PWM_DE_INIT_API )*/

#if (STD_ON == PWM_SET_DUTY_CYCLE_API)
/**********************************************************************************************************************
 *  Function Name : Pwm_SetDutyCycle
 *********************************************************************************************************************/
/*  \Description:This service sets the duty cycle for a channel
 *                  if DutyCycle is 0%, set output to idle state
 *                  if DutyCycle is >= 100%, set output to active state
 *                  if 0% < DutyCycle < 100%, set output signal accordingly
 *
 *  \param[in]  Pwm_ChannelType  ChannelNumber         number of the logical (!) channel
 *  \param[in]  uint16           DutyCycle               Duty cycle as percentage of period

 *  \return:     None
 *  \pre:        The module must be initialized when service is called
 *  \context:    Function could be called from interrupt level or from task level
 *********************************************************************************************************************/
/* SourceId : PWM_SourceId_017 */
/* DesignId : PWM_DesignId_16  */
/* Requirements : AR_PWM_SR49, AR_PWM_SR50, AR_PWM_SR51, AR_PWM_SR52, AR_PWM_SR53, AR_PWM_SR54 */
FUNC(void, PWM_CODE) Pwm_SetDutyCycle(Pwm_ChannelType ChannelNumber, uint16 DutyCycle)
{
   Pwm_HetType PwmHetFlag = HETCLR;
   uint8 Het1_ChannelOffset = 0U;
   uint8 Het2_ChannelOffset = 0U;

   /* ################### Begin dev error checks ######################### */

   /* check if the pwm driver has been initialized. if it is not, report
    * error PWM_E_UNINIT and return immediately.
    */
#if ( STD_ON == PWM_DEV_ERROR_DETECT )
   /* SourceId : PWM_SourceId_040 */
   /* DesignId : PWM_DesignId_16  */
   /* Requirements : AR_PWM_SR8, AR_PWM_SR94 */
   if ( PWM_STATUS_INIT != Pwm_Status_u8 )
   {
      /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
      Pwm_Errorhook( PWM_SID_SET_DUTY_CYCLE, PWM_E_UNINIT );
   }


   /* check if channel number is valid. if it is not, report error
    * PWM_E_PARAM_CHANNEL and return immediately
    */
   /* SourceId : PWM_SourceId_033 */
   /* DesignId : PWM_DesignId_16  */
   /* Requirements : AR_PWM_SR9, AR_PWM_SR96 */
   else if (Pwm_CurrentConfig_pt->NumberOfChannels_u8 <= ChannelNumber)
   {
 	 /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
	 Pwm_Errorhook(PWM_SID_SET_DUTY_CYCLE, PWM_E_PARAM_CHANNEL);
   }
  else
#endif /* ( STD_ON == PWM_DEV_ERROR_DETECT ) */

   {
      /*Find the Index of the channel to store the Dutycycle in the Het Ram*/
      Pwm_UpdateFlag(&PwmHetFlag, &Het1_ChannelOffset, &Het2_ChannelOffset, ChannelNumber);

      /* Period : The period is 25 bit value.
       * DutyCycle : Duty cycle is 16 bit value interpreted as percentage of the period.
       * The highest resolution for this percentage in the implementation,
         0x8000 is represented as 100% and 0x0000 is 0%*/

      /* ################### End dev error checks ########################### */
      if( HET1 == PwmHetFlag )
      {
    	  Pwm_HetSetDutyCycle(ChannelNumber, DutyCycle, Het1_ChannelOffset, PWM_HET1RAM, PWM_HET1_REG_ADDR);
      }
      else
      { /*Het2*/
    	  Pwm_HetSetDutyCycle(ChannelNumber, DutyCycle, Het2_ChannelOffset, PWM_HET2RAM, PWM_HET2_REG_ADDR);
      }
   }
}/* void Pwm_SetDutyCycle( ... ) */

/**********************************************************************************************************************
 *  Function Name : Pwm_HetSetDutyCycle
 *********************************************************************************************************************/
/*  \Description:This service sets the duty cycle for a channel in HET
 *  \param[in]  Pwm_ChannelType           ChannelNumber         number of the logical channel
 *  \param[in]  uint16                    DutyCycle             Duty cycle as percentage of period
 *  \param[in]  uint8                     Het1_ChannelOffset    corresponding channel offset in HET
 *  \param[in]  Het_Pwm_InstructionType*  HetRam                RAM Address of HET instructions
 *  \param[in]  Pwm_HetRegisterType*      HetReg                Register Base Address of HET
 *  \return:     None
 *  \context:    Function could be called from Pwm_SetDutyCycle only.
 *********************************************************************************************************************/
static FUNC(void, PWM_CODE) Pwm_HetSetDutyCycle (Pwm_ChannelType ChannelNumber, \
                                    uint16 DutyCycle, uint8 Het_ChannelOffset, P2VAR(Het_Pwm_InstructionType, PWM_VAR,\
                                    		HET_RAM) HetRam, P2VAR(Pwm_HetRegisterType, PWM_VAR, MSR_REGSPACE) HetReg )
{
   uint32 DutyCycleTics_u32 = 0U;

   /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Pwm_SetDutyCycle(..) is called post Pwm_Init(..)" */
   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  Volatile variable is required for accurate calculation"*/
   DutyCycleTics_u32 = (uint32)((((Pwm_Uint64)((HetRam[PWM_MOV_PERIOD_OFFSET + \
      Het_ChannelOffset].Data_u32 >> PWM_DUTYCYCLE_OFFSET ) + 1U )) * DutyCycle ) >> 15U );

      if ( (DutyCycleTics_u32 != 0U) && (DutyCycle < 0x8000U) )
      {
#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
         /* If  Pwm_SetDutyCycle is used to return from idle state, the Edge Notification
            Interrupts have to be restored */

         if( Pwm_NotifyActivationState_au8[ChannelNumber] != PWM_NO_EDGES )
         {
            /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - To set the IRQ of Het1" */
        	 PWM_HET_IRQ_SET = ((uint32)(1U) << (Het_ChannelOffset + PWM_CHANNEL_OFFSET));
         }
#endif /*(STD_ON == PWM_NOTIFICATION_SUPPORTED)*/
      }
      else /* Duty Cycle >= 0x8000  or Duty Cycle == 0 */
      {
         /* Duty cycle is set to maximum, so the end of period is always reached before*/
#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
         /* Duty Cycle is 100 %, but Het still produces interrupts
          * they have to be switched off                           */
         /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - To clear the IRQ of Het1" */
    	  PWM_HET_IRQ_CLEAR = ( (uint32)(1U) << (Het_ChannelOffset + PWM_CHANNEL_OFFSET));
#endif  /*(STD_ON == PWM_NOTIFICATION_SUPPORTED)*/
      }
      /* Duty Cycle is not zero, so the Pin action of for both must be set due to the
       *  current Polarity   */
      Pwm_GlobalSuspend();

      if(( Pwm_CurrentConfig_pt->ChannelConfig_at[ChannelNumber].Polarity_t) == PWM_HIGH )
      {
    	  /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  Volatile variable is required for accurate calculation"*/
    	  HetRam[PWM_MOV_DUTYCYCLE_OFFSET + Het_ChannelOffset].Control_u32 |= 0x18U;
      }
      else
      {
    	 /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  Volatile variable is required for accurate calculation"*/
    	  HetRam[PWM_MOV_DUTYCYCLE_OFFSET + Het_ChannelOffset].Control_u32 &= 0xFFFFFFE8U;
      }
   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  Volatile variable is required for accurate calculation"*/
      HetRam[PWM_MOV_DUTYCYCLE_OFFSET + Het_ChannelOffset].Data_u32  = \
      ( (DutyCycleTics_u32 + 1U) << PWM_DUTYCYCLE_OFFSET );
      HetRam[PWM_DJZ_OFFSET + Het_ChannelOffset].Data_u32  = 0U;
   Pwm_GlobalRestore();

}
#endif /*(STD_ON == PWM_SET_DUTY_CYCLE_API)*/

#if (STD_ON == PWM_SET_PERIOD_AND_DUTY_API)
/**********************************************************************************************************************
 *  Function Name : Pwm_SetPeriodAndDuty
 *********************************************************************************************************************/
/*  \Description:This service sets the period and duty cycle for a channel
 *  \param[in]:  Pwm_ChannelType     ChannelNumber         number of the logical (!) channel
 *  \param[in]:  Pwm_PeriodType      Period                period for the channel
 *  \param[in]:  uint16              DutyCycle             duty cycle as percentage of period (0%=0 and 100%=0x8000)
 *  \return:     None
 *  \pre         The module must be initialized when service is called
 *  \context:    Function could be called from interrupt level or from task level
 *  \note:       Returning from idle output state to Pwm output is only possible by calling this service
 *********************************************************************************************************************/
/* SourceId : PWM_SourceId_018 */
/* DesignId : PWM_DesignId_17  */
/* Requirements : AR_PWM_SR56, AR_PWM_SR57, AR_PWM_SR58, AR_PWM_SR59, AR_PWM_SR61 */
FUNC(void, PWM_CODE) Pwm_SetPeriodAndDuty ( Pwm_ChannelType ChannelNumber, Pwm_PeriodType Period, uint16 DutyCycle )
{
   Pwm_HetType PwmHetFlag = HETCLR;
   uint8 Het1_ChannelOffset = 0U;
   uint8 Het2_ChannelOffset = 0U;

   /* ################### Begin dev error checks ######################### */

   /* check if the pwm driver has been initialized. if it is not, report
    * error PWM_E_UNINIT and return immediately.
    */
#if ( STD_ON == PWM_DEV_ERROR_DETECT )
   /* SourceId : PWM_SourceId_041 */
   /* DesignId : PWM_DesignId_17  */
   /* Requirements : AR_PWM_SR8, AR_PWM_SR94 */
   if ( PWM_STATUS_INIT != Pwm_Status_u8 )
   {
      /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
      Pwm_Errorhook( PWM_SID_SET_PERIOD_AND_DUTY, PWM_E_UNINIT );
   }

   /* check if channel number is valid. if it is not, report error
    * PWM_E_PARAM_CHANNEL and return immediately
    */
   /* SourceId : PWM_SourceId_034 */
   	   /* DesignId : PWM_DesignId_17  */
   	   /* Requirements : AR_PWM_SR9, AR_PWM_SR96 */
   else if (Pwm_CurrentConfig_pt->NumberOfChannels_u8 <= ChannelNumber)
   {
	 /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
	  Pwm_Errorhook( PWM_SID_SET_PERIOD_AND_DUTY, PWM_E_PARAM_CHANNEL );
   }


   /* Check if this channel is from class "Variable Period", if it is fixed,
      report error PWM_E_PERIOD_UNCHANGEABLE */

   else if ( Pwm_CurrentConfig_pt->ChannelConfig_at[ChannelNumber].ChannelClass_t != PWM_VARIABLE_PERIOD )
   {
 	  /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
	  Pwm_Errorhook( PWM_SID_SET_PERIOD_AND_DUTY, PWM_E_PERIOD_UNCHANGEABLE );
   }

   /* check if period is 0. if it is, report error PWM_E_PARAM_PERIOD and
    * return immediately
    */


   else if (( 0U == Period ) || ( Period > PWM_PERIOD_MAX ))
   {
	  /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
	  Pwm_Errorhook( PWM_SID_SET_PERIOD_AND_DUTY, PWM_E_PARAM_PERIOD );
   }

   else
#endif /* ( STD_ON == PWM_DEV_ERROR_DETECT ) */
   {
      /*Find the Index of the channel to store the Dutycycle in the Het Ram*/
      Pwm_UpdateFlag(&PwmHetFlag, &Het1_ChannelOffset, &Het2_ChannelOffset, ChannelNumber);

      if( HET1 == PwmHetFlag )
      {
    	  Pwm_HetSetPeriodAndDuty(ChannelNumber, Period, DutyCycle, Het1_ChannelOffset, PWM_HET1RAM, PWM_HET1_REG_ADDR);
      }
      else/*Het2*/
      {
    	  Pwm_HetSetPeriodAndDuty(ChannelNumber, Period, DutyCycle, Het2_ChannelOffset, PWM_HET2RAM, PWM_HET2_REG_ADDR);
      }
   }
} /* void Pwm_SetPeriodAndDuty( ... ) */

/**********************************************************************************************************************
 *  Function Name : Pwm_HetSetPeriodAndDuty
 *********************************************************************************************************************/
/*  \Description:This service sets the period and duty cycle for a channel in HET
 *  \param[in]  Pwm_ChannelType           ChannelNumber         number of the logical channel
 *  \param[in]  Pwm_PeriodType            Period                period for the channel
 *  \param[in]  uint16                    DutyCycle             Duty cycle as percentage of period
 *  \param[in]  uint8                     Het1_ChannelOffset    corresponding channel offset in HET
 *  \param[in]  Het_Pwm_InstructionType*  HetRam                RAM Address of HET instructions
 *  \param[in]  Pwm_HetRegisterType*      HetReg                Register Base Address of HET
 *  \return:    None
 *  \context:   Function could be called from Pwm_SetPeriodandDuty only.
 *********************************************************************************************************************/
static FUNC(void, PWM_CODE) Pwm_HetSetPeriodAndDuty (Pwm_ChannelType ChannelNumber,  Pwm_PeriodType  Period,
                                   uint16 DutyCycle, uint8 Het_ChannelOffset, P2VAR(Het_Pwm_InstructionType, PWM_VAR,\
                                       		HET_RAM) HetRam, P2VAR(Pwm_HetRegisterType, PWM_VAR, MSR_REGSPACE) HetReg )
{
    uint32 DutyCycleTics_u32;

    DutyCycleTics_u32 = (uint32)(((Period * DutyCycle)) >> 15U );

	  if ( (DutyCycleTics_u32 != 0U) && (DutyCycle < 0x8000U) )
      {
        #if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
       /* If  Pwm_SetDutyCycle is used to return from idle state, the Edge Notification
          Interrupts have to be restored */
         if( Pwm_NotifyActivationState_au8[ChannelNumber] != PWM_NO_EDGES )
         {
            /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - To set the Het1 IRQ" */
           PWM_HET_IRQ_SET = ((uint32)(1U) << (Het_ChannelOffset + PWM_CHANNEL_OFFSET));
         }
        #endif /*(STD_ON == PWM_NOTIFICATION_SUPPORTED)*/
      }
      else /* Duty Cycle >= 0x8000  or Duty Cycle == 0 */
      {
        #if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
        /* Duty Cycle is 100 %, but Het still produces interrupts
         * they have to be switched off                           */
           /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - To clear the Het1 IRQ" */
          PWM_HET_IRQ_CLEAR = ((uint32)(1U) << (Het_ChannelOffset + PWM_CHANNEL_OFFSET));
        #endif /*(STD_ON == PWM_NOTIFICATION_SUPPORTED)*/
      }
      /* Duty Cycle is not zero, so the Pin action of for both must be set due to the
       * Polarity  */
      Pwm_GlobalSuspend();

      if(( Pwm_CurrentConfig_pt->ChannelConfig_at[ChannelNumber].Polarity_t) == PWM_HIGH )
      {
    	 /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  Volatile variable is required for accurate calculation"*/
    	  HetRam[PWM_MOV_DUTYCYCLE_OFFSET + Het_ChannelOffset].Control_u32 |= 0x18U;
      }
      else
      {
    	 /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  Volatile variable is required for accurate calculation"*/
    	  HetRam[PWM_MOV_DUTYCYCLE_OFFSET + Het_ChannelOffset].Control_u32 &= 0xFFFFFFE8U;
      }
    /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  Volatile variable is required for accurate calculation"*/
      HetRam[PWM_MOV_PERIOD_OFFSET + Het_ChannelOffset].Data_u32  = ((Period - 1U)  << PWM_DUTYCYCLE_OFFSET );
    /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -  Volatile variable is required for accurate calculation"*/
      HetRam[PWM_MOV_DUTYCYCLE_OFFSET + Het_ChannelOffset].Data_u32  = \
      ( (DutyCycleTics_u32 + 1U) << PWM_DUTYCYCLE_OFFSET );
      HetRam[PWM_DJZ_OFFSET + Het_ChannelOffset].Data_u32  = 0U;
    Pwm_GlobalRestore();
} /* void _Pwm_Het1SetPeriodAndDuty(...)*/

#endif /*(STD_ON == PWM_SET_PERIOD_AND_DUTY_API)*/


#if (STD_ON == PWM_SET_OUTPUT_TO_IDLE_API)
/**********************************************************************************************************************
 * Function Name : Pwm_SetOutputToIdle
 *********************************************************************************************************************/
/*  \Description: This service sets the output of a channel immediately to idle.
 *               The idle output level is deposited in configuration.
 *  \param[in]:  Pwm_ChannelType     ChannelNumber         number of the logical (!) channel
 *  \return:     None
 *  \pre:        The module must be initialized when service is called.
 *  \context:    Function could be called from interrupt level or from task level.
 *  \note:       Returning from idle output state to pwm output is only possible by calling Pwm_SetPeriodAndDuty.
 *********************************************************************************************************************/
/* SourceId : PWM_SourceId_019 */
/* DesignId : PWM_DesignId_18  */
/* Requirements : AR_PWM_SR62, AR_PWM_SR63, AR_PWM_SR66, AR_PWM_SR67 */
FUNC(void, PWM_CODE) Pwm_SetOutputToIdle( Pwm_ChannelType ChannelNumber )
{
   uint8 Het1_ChannelOffset = 0U;
   uint8 Het2_ChannelOffset = 0U;
   uint8 Het_ChannelOffset = ChannelNumber;
   /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - HetRam cannot be NULL" */
   Het_Pwm_InstructionType* HetRam ;
#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
   /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - HetReg cannot be NULL" */
   Pwm_HetRegisterType* HetReg ;
#endif

   /* ################### Begin dev error checks ######################### */

   /* check if the pwm driver has been initialized. if it is not, report
    * error PWM_E_UNINIT and return immediately.
    */
#if ( STD_ON == PWM_DEV_ERROR_DETECT )
   /* SourceId : PWM_SourceId_042 */
   /* DesignId : PWM_DesignId_18  */
   /* Requirements : AR_PWM_SR8, AR_PWM_SR94 */
   if ( PWM_STATUS_INIT != Pwm_Status_u8 )
   {
      /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
      Pwm_Errorhook( PWM_SID_SET_OUTPUT_TO_IDLE, PWM_E_UNINIT );
   }


   /* check if channel number is valid. if it is not, report error
    * PWM_E_PARAM_CHANNEL and return immediately
    */

   /* SourceId : PWM_SourceId_035 */
   /* DesignId : PWM_DesignId_18  */
   /* Requirements : AR_PWM_SR9, AR_PWM_SR96 */
   else if( Pwm_CurrentConfig_pt->NumberOfChannels_u8  <=  ChannelNumber )
   {
 	 /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
	  Pwm_Errorhook( PWM_SID_SET_OUTPUT_TO_IDLE, PWM_E_PARAM_CHANNEL );
   }

   else
#endif /* ( STD_ON == PWM_DEV_ERROR_DETECT ) */

   {
      /*Find the Index of the channel to store the Dutycycle in the Het Ram*/
	   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL_PTR comes from Compiler.h" */
      Pwm_UpdateFlag(NULL_PTR, &Het1_ChannelOffset, &Het2_ChannelOffset, ChannelNumber);

      if(Pwm_CurrentConfig_pt->ChannelConfig_at[ChannelNumber].Het_t == HET1)
	  {
    	  Het_ChannelOffset = Het1_ChannelOffset;

    	  HetRam = PWM_HET1RAM;
#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
    	  HetReg = PWM_HET1_REG_ADDR;
#endif
	  }
      else
      {
    	  Het_ChannelOffset = Het2_ChannelOffset;
    	  HetRam = PWM_HET2RAM;
#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
		  HetReg = PWM_HET2_REG_ADDR;
#endif
      }
#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
	 /* Disable Interrupts globally */
	 /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - To clear the Het1 IRQ" */
     /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - HetReg cannot be NULL" */
	 PWM_HET_IRQ_CLEAR = ((uint32)(1U) << (Het_ChannelOffset + PWM_CHANNEL_OFFSET));
#endif /*(STD_ON == PWM_NOTIFICATION_SUPPORTED)*/
	 Pwm_GlobalSuspend();
	 /* Set Pwm_DutyCycle to min or max according to to the Polarity and Idle State of the Channel */
	 if(Pwm_CurrentConfig_pt->ChannelConfig_at[ChannelNumber].IdleState_t == \
		Pwm_CurrentConfig_pt->ChannelConfig_at[ChannelNumber].Polarity_t )
	 {
		 /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - Volatile variable is required for accurate calculation"*/
		 /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - HetRam cannot be NULL" */
		 HetRam[PWM_MOV_DUTYCYCLE_OFFSET + Het_ChannelOffset].Data_u32 = \
										(PWM_PERIOD_MAX << PWM_DUTYCYCLE_OFFSET);
		 /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - Volatile variable is required for accurate calculation"*/
		 HetRam[PWM_PWCNT_OFFSET + Het_ChannelOffset].Data_u32 = \
								(PWM_PERIOD_MAX << PWM_DUTYCYCLE_OFFSET);
	 }
	 else
	 {
		 /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - HetRam cannot be NULL" */
		 HetRam[PWM_MOV_DUTYCYCLE_OFFSET + Het_ChannelOffset].Data_u32 = 0U;
		 /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - Volatile variable is required for accurate calculation"*/
		 HetRam[PWM_PWCNT_OFFSET + Het_ChannelOffset].Data_u32 = 0U;
	 }
	 Pwm_GlobalRestore();

   }/*End of if(Dev_Error_Detect != TRUE)*/
} /* void Pwm_SetOutputToIdle( ... ) */
#endif /*(STD_ON == PWM_SET_OUTPUT_TO_IDLE_API)*/

#if (STD_ON == PWM_GET_OUTPUT_STATE_API)
/**********************************************************************************************************************
 * Function Name :  Pwm_GetOutputState
 *********************************************************************************************************************/
/*  \Description: This service returns the current PWM output level
 *               of the channel which is referred by the parameter
 *  \param[in]:  Pwm_ChannelType     ChannelNumber         number of the logical (!) channel
 *  \return:     STD_LOW - The output level of Pwm channel is low.
 *  \return:     STD_HIGH - The output level of Pwm channel is high.
 *  \pre:        The module must be initialized when service is called.
 *  \context:    Function could be called from interrupt level or from task level.
 *********************************************************************************************************************/
/* SourceId : PWM_SourceId_020 */
/* DesignId : PWM_DesignId_19  */
/* Requirements : AR_PWM_SR68, AR_PWM_SR69 */
FUNC(Pwm_OutputStateType, PWM_CODE) Pwm_GetOutputState( Pwm_ChannelType ChannelNumber )
{

   /* SourceId : PWM_SourceId_046 */
   /* DesignId : PWM_DesignId_19  */
   /* Requirements : AR_PWM_SR93 */
   Pwm_OutputStateType Output_Level = PWM_LOW;

   /* check driver state */
#if ( STD_ON == PWM_DEV_ERROR_DETECT )
   /* SourceId : PWM_SourceId_043 */
   /* DesignId : PWM_DesignId_19  */
   /* Requirements : AR_PWM_SR8, AR_PWM_SR94 */
   if ( PWM_STATUS_INIT != Pwm_Status_u8 )
   {
      /* driver has not been initialized --> report an error
       */
      /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
      Pwm_Errorhook( PWM_SID_GET_OUTPUT_STATE, PWM_E_UNINIT );
   }

   /* check channel number */

   /* SourceId : PWM_SourceId_036 */
   /* DesignId : PWM_DesignId_19  */
   /* Requirements : AR_PWM_SR9, AR_PWM_SR96 */

   else if( Pwm_CurrentConfig_pt->NumberOfChannels_u8  <=  ChannelNumber )
   {
 	 /* channel number is not valid --> report an error
	  */
  	 /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
 	 Pwm_Errorhook( PWM_SID_GET_OUTPUT_STATE, PWM_E_PARAM_CHANNEL );
   } /* if ( Pwm_HWChannelNumber_u8 <= ChannelNumber ) */

   else
#endif /* #if ( STD_ON == PWM_DEV_ERROR_DETECT ) */
   {
      if(Pwm_CurrentConfig_pt->ChannelConfig_at[ChannelNumber].Het_t == HET1)
      {
         /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -Output pin value compared with PWM_HET1_DATA_OUT" */
         if( (uint32)0x0U == ( PWM_HET1_DATA_OUT & ( (uint32)(1U) << \
            (uint32)Pwm_CurrentConfig_pt->ChannelConfig_at[ChannelNumber].OutputPin_u8 )))
         {
            Output_Level = PWM_LOW;
         }
         else
         {
            Output_Level = PWM_HIGH;
         }
      }
      else
      {
         /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason -Output pin value compared with PWM_HET2_DATA_OUT" */
         if( (uint32)0x0U == ( PWM_HET2_DATA_OUT & ( (uint32)(1U) << \
            (uint32)Pwm_CurrentConfig_pt->ChannelConfig_at[ChannelNumber].OutputPin_u8 )))
         {
            Output_Level = PWM_LOW;
         }
         else
         {
            Output_Level = PWM_HIGH;
         }
      }
   }
   return Output_Level;
} /* Pwm_OutputStateType Pwm_GetOutputState( ... ) */
#endif /*(STD_ON == PWM_GET_OUTPUT_STATE_API)*/

#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
/**********************************************************************************************************************
 *  Function Name : Pwm_DisableNotification
 *********************************************************************************************************************/
/*  \Description:Deactivates the Edge Notification
 *              This service deactivates the Edge Notification for the
 *              pwm channel specified by the ChannelNumber Parameter
 *
 *  \param[in]  Pwm_ChannelType     ChannelNumber         number of the logical (!) channel
 *  \pre        The module must be initialized when service is called
 *  \context    Function could be called from interrupt level or from task level
 *********************************************************************************************************************/
/* SourceId : PWM_SourceId_021 */
/* DesignId : PWM_DesignId_20  */
/* Requirements : AR_PWM_SR71, AR_PWM_SR72 */
FUNC(void, PWM_CODE) Pwm_DisableNotification( Pwm_ChannelType ChannelNumber )
{
   uint8 Het1_ChannelOffset = 0U;
   uint8 Het2_ChannelOffset = 0U;
   uint8 Het_ChannelOffset = ChannelNumber;
   /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - HetRam cannot be NULL" */
   Het_Pwm_InstructionType* HetRam ;
   /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - HetReg cannot be NULL" */
   Pwm_HetRegisterType* HetReg ;


   /* check if the pwm driver has been initialized. if it is not, report
    * error PWM_E_UNINIT and return immediately.
    */
#if ( STD_ON == PWM_DEV_ERROR_DETECT )
   /* SourceId : PWM_SourceId_044 */
   /* DesignId : PWM_DesignId_20  */
   /* Requirements : AR_PWM_SR8, AR_PWM_SR94 */
   if ( PWM_STATUS_INIT != Pwm_Status_u8 )
   {
      /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
      Pwm_Errorhook( PWM_SID_DISABLE_NOTIFICATION, PWM_E_UNINIT );
   }


   /* SourceId : PWM_SourceId_037 */
   /* DesignId : PWM_DesignId_20  */
   /* Requirements : AR_PWM_SR9, AR_PWM_SR96 */
   else if ( Pwm_CurrentConfig_pt->NumberOfChannels_u8  <=  ChannelNumber )
   {
	  /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
 	  Pwm_Errorhook( PWM_SID_DISABLE_NOTIFICATION, PWM_E_PARAM_CHANNEL );
   }

   else
#endif /* ( STD_ON == PWM_DEV_ERROR_DETECT ) */
   {
      /*Find the Index of the channel to store the Dutycycle in the Het Ram*/
	   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL_PTR comes from Compiler.h" */
      Pwm_UpdateFlag(NULL_PTR, &Het1_ChannelOffset, &Het2_ChannelOffset, ChannelNumber);

      if(Pwm_CurrentConfig_pt->ChannelConfig_at[ChannelNumber].Het_t == HET1)
      {
    	  Het_ChannelOffset = Het1_ChannelOffset;
    	  HetRam = PWM_HET1RAM;
    	  HetReg = PWM_HET1_REG_ADDR;
      }
      else
      {
    	  Het_ChannelOffset = Het2_ChannelOffset;
    	  HetRam = PWM_HET2RAM;
    	  HetReg = PWM_HET2_REG_ADDR;
      }
	  /* Globally deactivate interrupts for this channel*/
	  /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - To clear the Het1 IRQ" */
      /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - HetReg cannot be NULL" */
	  PWM_HET_IRQ_CLEAR = ((uint32)(1U) << (Het_ChannelOffset + PWM_CHANNEL_OFFSET));

	  /* Disable the interrupts within the Het program */
	  Pwm_GlobalSuspend();
	  /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - HetRam cannot be NULL" */
	  /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - Volatile variable is required for accurate calculation"*/
	  HetRam[PWM_MOV_PERIOD_OFFSET + Het_ChannelOffset].Control_u32 &= 0xFFFFFFFEU;
	  /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - Volatile variable is required for accurate calculation"*/
 	  HetRam[PWM_MOV_DUTYCYCLE_OFFSET + Het_ChannelOffset].Control_u32 &= 0xFFFFFFFEU;
	  Pwm_GlobalRestore();


      /* Store the Notification state in module global variable */
      Pwm_NotifyActivationState_au8[ChannelNumber] = PWM_NO_EDGES;
   }
}
#endif /* #if (STD_ON == PWM_NOTIFICATION_SUPPORTED)*/

#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
/**********************************************************************************************************************
 *   Function Name : Pwm_EnableNotification
 *********************************************************************************************************************/
/*  \Description: Activates the Edge Notification
 *
 *              This service activates the notification of the chosen edges for the
 *              Pwm channel specified by the ChannelNumber parameter.
 *
 *  \param[in]:  Pwm_ChannelType           ChannelNumber        number of the logical (!) channel
 *  \param[in]:  Pwm_EdgeNotificationType  Notification         type of edge to enable notification
 *  \pre:        The module must be initialized when service is called
 *  \context:    Function could be called from interrupt level or from task level
 *********************************************************************************************************************/
/* SourceId : PWM_SourceId_022 */
/* DesignId : PWM_DesignId_21  */
/* Requirements : AR_PWM_SR75, AR_PWM_SR76, AR_PWM_SR77 */
FUNC(void, PWM_CODE) Pwm_EnableNotification ( Pwm_ChannelType ChannelNumber, Pwm_EdgeNotificationType Notification )
{
   /*SAFETYMCUSW 91 S MR:5.2 <APPROVED> "Reason - Since this is a local variable which has local scope" */
   uint8 Het1_ChannelOffset = 0U;
   uint8 Het2_ChannelOffset = 0U;

   /* check if the pwm driver has been initialized. if it is not, report
    * error PWM_E_UNINIT and return immediately.
    */
#if ( STD_ON == PWM_DEV_ERROR_DETECT )
   /* SourceId : PWM_SourceId_045 */
   /* DesignId : PWM_DesignId_21  */
   /* Requirements : AR_PWM_SR8, AR_PWM_SR94 */
   if ( PWM_STATUS_INIT != Pwm_Status_u8 )
   {
      /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
      Pwm_Errorhook( PWM_SID_ENABLE_NOTIFICATION, PWM_E_UNINIT );
   }


   /* SourceId : PWM_SourceId_038 */
   /* DesignId : PWM_DesignId_21  */
   /* Requirements : AR_PWM_SR9, AR_PWM_SR96 */
   else if ( Pwm_CurrentConfig_pt->NumberOfChannels_u8  <=  ChannelNumber )
   {
	  /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
	  Pwm_Errorhook( PWM_SID_ENABLE_NOTIFICATION, PWM_E_PARAM_CHANNEL );
   }

   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL_PTR comes from Compiler.h" */
   else if ( Pwm_CurrentConfig_pt->ChannelConfig_at[ChannelNumber].NotificationFunc_pt == NULL_PTR )
   {
	  /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
	  Pwm_Errorhook( PWM_SID_ENABLE_NOTIFICATION, PWM_E_NOTIFY_NULL );
   }

   else
#endif /* #if (STD_ON == PWM_DEV_ERROR_DETECT)*/
   {
      /*Find the Index of the channel to store the Dutycycle in the Het Ram*/
	   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL_PTR comes from Compiler.h" */
      Pwm_UpdateFlag(NULL_PTR, &Het1_ChannelOffset, &Het2_ChannelOffset, ChannelNumber);

      if(Pwm_CurrentConfig_pt->ChannelConfig_at[ChannelNumber].Het_t == HET1)
      {
    	  Pwm_HetEnableNotification(ChannelNumber, Notification, Het1_ChannelOffset, PWM_HET1RAM, PWM_HET1_REG_ADDR);
      }
      else
      {
    	  Pwm_HetEnableNotification(ChannelNumber, Notification, Het2_ChannelOffset, PWM_HET2RAM, PWM_HET2_REG_ADDR);
      }
      Pwm_NotifyActivationState_au8[ChannelNumber] = PWM_EDGE;
   }
}

/**********************************************************************************************************************
 *  Function Name : Pwm_HetEnableNotification
 *********************************************************************************************************************/
/*  \Description: This service that enables notification for a channel in any HET
 *  \param[in]  Pwm_ChannelType           ChannelNumber         number of the logical (!) channel
 *  \param[in]  Pwm_EdgeNotificationType  Notification          type of edge to enable notification
 *  \param[in]  uint8                     Het_ChannelOffset     corresponding channel offset in HET
 *  \param[in]  Het_Pwm_InstructionType*  HetRam                RAM Address of HET instructions
 *  \param[in]  Pwm_HetRegisterType*      HetReg                Register Base Address of HET
 *  \return:     None
 *  \context:    Function could be called from Pwm_EnableNotification only.
 *********************************************************************************************************************/
static FUNC(void, PWM_CODE) Pwm_HetEnableNotification (Pwm_ChannelType ChannelNumber,
                        Pwm_EdgeNotificationType Notification, uint8 Het_ChannelOffset, P2VAR(Het_Pwm_InstructionType,\
                            	   PWM_VAR, HET_RAM) HetRam, P2VAR(Pwm_HetRegisterType, PWM_VAR, MSR_REGSPACE) HetReg )
{
   Pwm_OutputStateType Polarity = PWM_LOW;
   uint32 CurrentDutyCycle_u32 = 0U;

   /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - It is checked for NULL in Pwm_EnableNotification(..)" */
   Polarity = Pwm_CurrentConfig_pt->ChannelConfig_at[ChannelNumber].Polarity_t;
   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - To clear the Het1 IRQ" */
   /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - Pwm_SetDutyCycle(..) is called post Pwm_Init(..)" */
   PWM_HET_IRQ_CLEAR = ((uint32)(1U) << (Het_ChannelOffset + PWM_CHANNEL_OFFSET));

   /*Enable the Interrupt enable bits in the Control field of ECMP instruction for both Period and Duty cycle.*/
   if((( Notification == PWM_RISING_EDGE ) && ( Polarity  == PWM_HIGH )) || \
      (( Notification == PWM_FALLING_EDGE) && ( Polarity  == PWM_LOW )))
   {
      Pwm_GlobalSuspend();
      /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - Volatile variable is required for accurate calculation"*/
      HetRam[PWM_MOV_DUTYCYCLE_OFFSET + Het_ChannelOffset].Control_u32 &= 0xFFFFFFFEU;
      /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - Volatile variable is required for accurate calculation"*/
      HetRam[PWM_MOV_PERIOD_OFFSET + Het_ChannelOffset].Control_u32 |= 0x1U;
      Pwm_GlobalRestore();
   }
   else if( Notification != PWM_BOTH_EDGES )
   {
      Pwm_GlobalSuspend();
      /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - Volatile variable is required for accurate calculation"*/
      HetRam[PWM_MOV_PERIOD_OFFSET + Het_ChannelOffset].Control_u32 &= 0xFFFFFFFEU;
      /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - Volatile variable is required for accurate calculation"*/
      HetRam[PWM_MOV_DUTYCYCLE_OFFSET + Het_ChannelOffset].Control_u32 |= 0x1U;
      Pwm_GlobalRestore();
   }
   /*Enable both interrupts in the control field of ECMP instruction*/
   else
   {
      Pwm_GlobalSuspend();
      /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - Volatile variable is required for accurate calculation"*/
      HetRam[PWM_MOV_PERIOD_OFFSET + Het_ChannelOffset].Control_u32 |= 0x1U;
      /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - Volatile variable is required for accurate calculation"*/
      HetRam[PWM_MOV_DUTYCYCLE_OFFSET + Het_ChannelOffset].Control_u32 |= 0x1U;
      Pwm_GlobalRestore();
   }

   /* The following section shall not be interrupted by Pwm_SetPeriodAndDuty or Pwm_SetDutyCycle */
   Pwm_GlobalSuspend();
   /* Only enable the Interrupts globally, if the duty cycle is not 0% or 100% */
   /*SAFETYMCUSW 408 S MR:12.4 <APPROVED> "Reason - To find the current dutycycle of the PWM channel" */
   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - Volatile variable is required for accurate calculation"*/
   CurrentDutyCycle_u32 = ( HetRam[PWM_MOV_DUTYCYCLE_OFFSET + \
                                        Het_ChannelOffset].Data_u32 >> PWM_DUTYCYCLE_OFFSET );
   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - Volatile variable is required for accurate calculation"*/
   if( ( CurrentDutyCycle_u32 > (uint32)(1U) ) && ( CurrentDutyCycle_u32 < \
      ((HetRam[PWM_MOV_PERIOD_OFFSET  + Het_ChannelOffset ].Data_u32 >> PWM_DUTYCYCLE_OFFSET) + 1U )))
   {
      /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - To set the Het1 IRQ" */
      PWM_HET_IRQ_SET = ((uint32)(1U) << (Het_ChannelOffset + PWM_CHANNEL_OFFSET));
   }
   Pwm_GlobalRestore();

} /*void Pwm_HetEnableNotification(...)*/

#endif /* #if ( STD_ON == PWM_NOTIFICATION_SUPPORTED ) */

#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
/**********************************************************************************************************************
 *   Function Name : Pwm_Het1EdgeNotificationISR
 *********************************************************************************************************************/
/*! \Description: Interrupt Subroutine for Het1 Edge Notification
 *
 *  \context    Function is called from interrupt level
 *********************************************************************************************************************/
/*SAFETYMCUSW 69 S MR:3.4 <APPROVED> "Reason -  Pragma is required here for functions in ISR"*/
#pragma CODE_STATE(Pwm_Het1EdgeNotificationISR, 32)
FUNC(void, PWM_CODE) Pwm_Het1EdgeNotificationISR( void )
{
   /* Reading the OFFSET register also clears IRQ flag */
   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - To store HET1 offset register" */
   uint32 IrqSource_u32 = PWM_HET1_OFF2;
   uint8 ChannelNumber = 0U;


   /* The Interrupt sources 16 - 31 are belonging to Pwm and mapped to Offset 17 - 32 */
   /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason - Check if IRQ source is valid" */
   if( IrqSource_u32 >= PWM_IRQ_CHANNEL_OFFSET )
   {
      /* Offset - 17 is the channel */
      ChannelNumber = (uint8)Pwm_UpdateChannelNumber((Pwm_HetType)HET1, (uint32)(IrqSource_u32 - PWM_IRQ_CHANNEL_OFFSET));
      Pwm_CurrentConfig_pt->ChannelConfig_at[ChannelNumber].NotificationFunc_pt();
   }
}
#endif /*(STD_ON == PWM_NOTIFICATION_SUPPORTED)*/

#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
/**********************************************************************************************************************
 *   Function Name : Pwm_Het2EdgeNotificationISR
 *********************************************************************************************************************/
/*! \Description: Interrupt Subroutine for Het2 Edge Notification
 *
 *  \context    Function is called from interrupt level
 *********************************************************************************************************************/
/*SAFETYMCUSW 69 S MR:3.4 <APPROVED> "Reason -  Pragma is required here for functions in ISR"*/
#pragma CODE_STATE(Pwm_Het2EdgeNotificationISR, 32)
FUNC(void, PWM_CODE) Pwm_Het2EdgeNotificationISR( void )
{
   /* Reading the OFFSET register also clears IRQ flag */
   /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "Reason - To get offset2 register value which is volatile" */
   uint32 IrqSource_u32 = PWM_HET2_OFF2;
   uint8 ChannelNumber = 0U;

   /* The Interrupt sources 16 - 31 are belonging to Pwm and mapped to Offset 17 - 32 */
   /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason - Check if IRQ source is valid" */
   if( IrqSource_u32 >= PWM_IRQ_CHANNEL_OFFSET )
   {
      /* Offset - 17 is the channel */
	  ChannelNumber = (uint8)Pwm_UpdateChannelNumber((Pwm_HetType)HET2, (uint32)(IrqSource_u32 - PWM_IRQ_CHANNEL_OFFSET));
      Pwm_CurrentConfig_pt->ChannelConfig_at[ChannelNumber].NotificationFunc_pt();
   }
}
#endif /*(STD_ON == PWM_NOTIFICATION_SUPPORTED)*/

#if (STD_ON == PWM_SAFETI_API)
/**********************************************************************************************************************
 *   Function Name : Pwm_ConfigRegReadBack
 *********************************************************************************************************************/
/*! \Description: Register readback to check if static registers have expected values.
 *
 *  \param[in]  : Pwm_HetType      Het                    HET to read configuration registers from.
 *  \param[out] : PwmConfigReg*    PwmConfigReg_pt        Pointer to where to store the register
 *                                                        values which are to be read.
 *  \return     : uint8            Dev_Error_Detect       Value of error if present. 0 otherwise.
 *  \context    : Function is called from top layer applications.
 *********************************************************************************************************************/
/* SourceId : PWM_SourceId_050 */
/* DesignId : PWM_DesignId_23  */
/* Requirements : AR_PWM_SR124 */

FUNC(Std_ReturnType, PWM_CODE) Pwm_ConfigRegReadBack(Pwm_HetType Het, PwmConfigReg* PwmConfigReg_pt)
{
	Std_ReturnType Dev_Error_Detect = E_NOT_OK;
	uint32 HetRegAddr = (uint32)PWM_HET1_REG_ADDR;
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL_PTR comes from Compiler.h" */
   if ( NULL_PTR == PwmConfigReg_pt )
   {
	   /* Do Nothing */
   }
   else if((Het != HET1) && (Het != HET2))
   {
	   /* Do Nothing */
   }

#if ( STD_ON == PWM_DEV_ERROR_DETECT )
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL_PTR comes from Compiler.h" */
   else if ( PWM_STATUS_INIT != Pwm_Status_u8 )
   {
	   /* Do Nothing */
   }
#endif
   /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Reason - Construct does not lead to infeasible code" */
   else
   {
	   if( HET1 == Het )
	   {

	   }
	   else
	   {
		   HetRegAddr = (uint32)PWM_HET2_REG_ADDR;
	   }
	   PwmConfigReg_pt->Pwm_ReadBack_GCR  = HET_CGR(HetRegAddr);/*Reg address of GCR*/
	   PwmConfigReg_pt->Pwm_ReadBack_PFR  = HET_PFR(HetRegAddr);/*Reg address of PFR*/
	   PwmConfigReg_pt->Pwm_ReadBack_PRY  = HET_PRY(HetRegAddr);/*Reg address of PRY*/
	   PwmConfigReg_pt->Pwm_ReadBack_DIR  = HET_DIR(HetRegAddr);/*Reg address of DIR*/
	   PwmConfigReg_pt->Pwm_ReadBack_PDR  = HET_PDR(HetRegAddr);/*Reg address of PDR*/
	   PwmConfigReg_pt->Pwm_ReadBack_PDIS = HET_PULLDIS(HetRegAddr);/*Reg address of PDIS*/
	   PwmConfigReg_pt->Pwm_ReadBack_PSL  = HET_PSL(HetRegAddr);/*Reg address of PSL*/
	   Dev_Error_Detect = E_OK;
   }
   return Dev_Error_Detect;
}

#endif

#if (STD_ON == PWM_VERSION_INFO_API)
/**********************************************************************************************************************
 * Function Name : Pwm_GetVersionInfo
 *********************************************************************************************************************/
/* \Description:This service returns the version information of this module.
 *
 *               The version information includes:
 *              - Module Id
 *              - Vendor Id
 *              - Vendor specific version numbers
 *
 *  \param[out]: Std_VersionInfoType  versioninfo        Pointer to where to store the version
 *                                                       information of this module.
 *  \context:    The function can be called on task level.
 *
 *********************************************************************************************************************/
/* SourceId : PWM_SourceId_023 */
/* DesignId : PWM_DesignId_22  */
/* Requirements : AR_PWM_SR80, AR_PWM_SR81, AR_PWM_SR84 */
FUNC(void, PWM_CODE) Pwm_GetVersionInfo ( P2VAR(Std_VersionInfoType, AUTOMATIC, PWM_APPL_DATA) versioninfo )
{


#if (STD_ON == PWM_DEV_ERROR_DETECT)
   /* SourceId : PWM_SourceId_006 */
   /* DesignId : PWM_DesignId_22  */
   /* Requirements : AR_PWM_SR12 */
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL_PTR comes from Compiler.h" */
   if (NULL_PTR == versioninfo)
   {
      /* Call Errorhook with 'wrong parameter'. */
      /*SAFETYMCUSW 382 S MR:16.10 <APPROVED> "Reason - Det error return value not required." */
      Pwm_Errorhook(PWM_SID_GET_VERSION_INFO, PWM_E_PARAM_POINTER);
      /* Return from function because of error. */
   }
   else
#endif
   {
      versioninfo->vendorID         = ( PWM_VENDOR_ID );
      versioninfo->moduleID         = ( PWM_MODULE_ID );
      versioninfo->sw_major_version = (uint8)( PWM_SW_MAJOR_VERSION );
      versioninfo->sw_minor_version = (uint8)( PWM_SW_MINOR_VERSION );
      versioninfo->sw_patch_version = (uint8)( PWM_SW_PATCH_VERSION );
   }
}/* Pwm_GetVersionInfo() */
#endif  /*(PWM_VERSION_INFO_API == STD_ON)*/

#if ((STD_ON == PWM_SET_DUTY_CYCLE_API) || (STD_ON == PWM_SET_PERIOD_AND_DUTY_API) || \
     (STD_ON == PWM_SET_OUTPUT_TO_IDLE_API) || (STD_ON == PWM_NOTIFICATION_SUPPORTED))
/**********************************************************************************************************************
 *  Function Name : Pwm_UpdateFlag
 *********************************************************************************************************************/
/*  \Description:This function updates required variables
 *
 *  \param[in]  &Pwm_HetType  *PwmHetFlag          address of flag indicating the type of HET
 *  \param[in]  &uint8        *Het1_ChannelOffset  address of HET1 channel offset
 *  \param[in]  &uint8        *Het2_ChannelOffset  address of HET2 channel offset
 *  \param[in]  Pwm_ChannelType  ChannelNumber    number of the logical (!) channel
 *  \return:    Updated values of first three variables
 *  \context:   Function can be called from any API
 *********************************************************************************************************************/
/*SAFETYMCUSW 458 S MR:10.1,10.2 <APPROVED> "Reason - Tool issue"*/
static FUNC(void, PWM_CODE) Pwm_UpdateFlag(Pwm_HetType* PwmHetFlagPtr, uint8* Het1_ChannelOffsetPtr, \
        uint8* Het2_ChannelOffsetPtr, Pwm_ChannelType ChannelNumber)
{
   Pwm_HetType PwmHetFlag = HETCLR;
   uint8 NoOfChannels = 0U;
   uint8 Count = 0U;
   uint8 Het1ChannelOffset = 0U;
   uint8 Het2ChannelOffset = 0U;

   /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - It is checked for NULL in respective callee functions" */
   NoOfChannels = Pwm_CurrentConfig_pt->NumberOfChannels_u8;
   /*Find the Index of the channel to store the Dutycycle in the Het Ram*/
   for(Count = 0U;Count < NoOfChannels;Count++)
   {
      if(Pwm_CurrentConfig_pt->ChannelConfig_at[Count].Het_t == HET1)
      {
         if(Count == ChannelNumber)
         {
            PwmHetFlag = HET1;
         }
         else
         {
            Het1ChannelOffset = Het1ChannelOffset + 1U;
         }
      }
      else
      {
         if(Count == ChannelNumber)
         {
            PwmHetFlag = HET2;
         }
         else
         {
            Het2ChannelOffset = Het2ChannelOffset + 1U;
         }
      }
      if(HETCLR != PwmHetFlag)
      {
    	  break;
      }
   }
   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL_PTR comes from Compiler.h" */
   if (PwmHetFlagPtr != NULL_PTR) {
      *PwmHetFlagPtr = PwmHetFlag;
   }
   *Het1_ChannelOffsetPtr = Het1ChannelOffset;
   *Het2_ChannelOffsetPtr = Het2ChannelOffset;
} /*void Pwm_UpdateFlag(...)*/
#endif

#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
/**********************************************************************************************************************
 *  Function Name : Pwm_UpdateChannelNumber
 *********************************************************************************************************************/
/*  \Description:This function returns the logical channel number taking the HET and Het offset as input.
 *
 *  \param[in]  Pwm_HetType  PwmHet              flag indicating the type of HET
 *  \param[in]  uint8        Het_ChannelOffset   HET channel offset
 *  \return:    Pwm_ChannelType  ChannelNumber    number of the logical (!) channel
 *  \context:   Function can be called from any API which is called after Pwm_Init
 *********************************************************************************************************************/
/*SAFETYMCUSW 69 S MR:3.4 <APPROVED> "Reason -  Pragma is required here for functions in ISR"*/
#pragma CODE_STATE(Pwm_UpdateChannelNumber, 32)
static FUNC(Pwm_ChannelType, PWM_CODE) Pwm_UpdateChannelNumber(Pwm_HetType PwmHet, uint32 Het_ChannelOffset)
{
   Pwm_ChannelType ChannelNumber = 0U;
   /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Reason - This will always be called after Pwm_Init()" */
   uint8 NoOfChannels = Pwm_CurrentConfig_pt->NumberOfChannels_u8;
   uint8 Count;
   uint32 HetChannelCount = 0U;
   for(Count = 0U; Count < NoOfChannels; Count++)
   {
	  if(Pwm_CurrentConfig_pt->ChannelConfig_at[Count].Het_t == PwmHet)
	  {
		 if(HetChannelCount == Het_ChannelOffset)
		 {
			 ChannelNumber = Count;
			 break;
		 }
		 else
		 {
			 HetChannelCount++;
		 }
	  }
   }

   /*SAFETYMCUSW 440 S MR:11.3 <APPROVED> "Reason - NULL_PTR comes from Compiler.h" */
   return ChannelNumber;
} /*void Pwm_UpdateFlag(...)*/
#endif

/*SAFETYMCUSW 580 S MR:1.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#define PWM_STOP_SEC_CODE
/*SAFETYMCUSW 338 S MR:19.1 <APPROVED> "Reason - This is the format for specifying memory sections" */
#include "MemMap.h"
/**********************************************************************************************************************
 *  END OF FILE: Pwm.c
 *********************************************************************************************************************/
