/**
*   @file           Pwm_Ipw.c
*   @version        1.0.0
*
*   @brief          AUTOSAR Pwm - PWM IP wrapper API implementation.
*   @details        PWM IP wrapper API implementation.
*
*   @addtogroup     PWM_MODULE
*   @{
*/
/*==================================================================================================
*   Project              : AUTOSAR 4.3 MCAL
*   Platform             : PA
*   Peripheral           : eMios
*   Dependencies         : none
*
*   AUTOSAR Version      : 4.3.1
*   AUTOSAR Revision     : ASR_REL_4_3_REV_0001
*   AUTOSAR Conf.Variant :
*   SW Version           : 1.0.0
*   Build Version        : MPC5777C_MCAL_1_0_0_RTM_ASR_REL_4_3_REV_0001_20190315
*
*   (c) Copyright 2006-2016 Freescale Semiconductor, Inc. 
*       Copyright 2017-2019 NXP
*   All Rights Reserved.
==================================================================================================*/
/*==================================================================================================
==================================================================================================*/

#ifdef __cplusplus
extern "C"{
#endif

/**
* @page misra_violations MISRA-C:2012 violations
*
* @section [global]
* Violates MISRA 2012 Required Rule 5.1, External identifiers shall be distinct.
* The used compilers use more than 31 chars for identifiers.
*
* @section [global]
* Violates MISRA 2012 Required Rule 5.2, Identifiers declared in the same scope and name space shall be distinct.
* The used compilers use more than 31 chars for identifiers.
*
* @section [global]
* Violates MISRA 2012 Required Rule 5.4, Macro identifiers shall be distinct.
* The used compilers use more than 31 chars for identifiers.
*
* @section [global]
* Violates MISRA 2012 Required Rule 5.5, Identifiers shall be distinct from macro names.
* The used compilers use more than 31 chars for identifiers.
*
* @section Pwm_Ipw_c_REF_1
* Violates MISRA 2012 Advisory Rule 20.1, #include directives should only be preceded by preprocessor directives or comments.
* <MA>_MemMap.h is included after each section define in order to set the current memory section as defined by AUTOSAR.
*
* @section Pwm_Ipw_c_REF_2
* Violates MISRA 2012 Required Directive 4.10, Precautions shall be taken in order to prevent the contents of a header
* file being included more than once.
* This violation is not fixed since the inclusion of <MA>_MemMap.h is as per AUTOSAR requirement [SWS_MemMap_00003].
*
*/



/*===============================================================================================
*                                         INCLUDE FILES
* 1) system and project includes
* 2) needed interfaces from external units
* 3) internal and external interfaces from this unit
===============================================================================================*/

#include "Pwm_Ipw.h"
#include "Pwm_Ipw_Notif.h"

#include "Pwm_eMios.h"



/*===============================================================================================
*                                        SOURCE FILE VERSION INFORMATION
===============================================================================================*/

/**
* @{
* @file           Pwm_Ipw.c
*/
#define PWM_IPW_VENDOR_ID_C                     43
#define PWM_IPW_AR_RELEASE_MAJOR_VERSION_C      4
#define PWM_IPW_AR_RELEASE_MINOR_VERSION_C      3
#define PWM_IPW_AR_RELEASE_REVISION_VERSION_C   1
#define PWM_IPW_SW_MAJOR_VERSION_C              1
#define PWM_IPW_SW_MINOR_VERSION_C              0
#define PWM_IPW_SW_PATCH_VERSION_C              0
/**@}*/



/*===============================================================================================
*                                      FILE VERSION CHECKS
===============================================================================================*/

#if (PWM_IPW_VENDOR_ID_C != PWM_IPW_VENDOR_ID)
    #error "Pwm_Ipw.c and Pwm_Ipw.h have different vendor ids"
#endif

#if ((PWM_IPW_AR_RELEASE_MAJOR_VERSION_C    != PWM_IPW_AR_RELEASE_MAJOR_VERSION) || \
     (PWM_IPW_AR_RELEASE_MINOR_VERSION_C    != PWM_IPW_AR_RELEASE_MINOR_VERSION) || \
     (PWM_IPW_AR_RELEASE_REVISION_VERSION_C != PWM_IPW_AR_RELEASE_REVISION_VERSION))
    #error "AUTOSAR Version Numbers of Pwm_Ipw.c and Pwm_Ipw.h are different"
#endif

#if ((PWM_IPW_SW_MAJOR_VERSION_C != PWM_IPW_SW_MAJOR_VERSION) || \
     (PWM_IPW_SW_MINOR_VERSION_C != PWM_IPW_SW_MINOR_VERSION) || \
     (PWM_IPW_SW_PATCH_VERSION_C != PWM_IPW_SW_PATCH_VERSION))
    #error "Software Version Numbers of Pwm_Ipw.c and Pwm_Ipw.h are different"
#endif



#if (PWM_IPW_VENDOR_ID_C != PWM_EMIOS_VENDOR_ID)
    #error "Pwm_Ipw.c and Pwm_eMios.h have different vendor ids"
#endif

#if ((PWM_IPW_AR_RELEASE_MAJOR_VERSION_C    != PWM_EMIOS_AR_RELEASE_MAJOR_VERSION) || \
     (PWM_IPW_AR_RELEASE_MINOR_VERSION_C    != PWM_EMIOS_AR_RELEASE_MINOR_VERSION) || \
     (PWM_IPW_AR_RELEASE_REVISION_VERSION_C != PWM_EMIOS_AR_RELEASE_REVISION_VERSION))
    #error "AUTOSAR Version Numbers of Pwm_Ipw.c and Pwm_eMios.h are different"
#endif

#if ((PWM_IPW_SW_MAJOR_VERSION_C != PWM_EMIOS_SW_MAJOR_VERSION) || \
     (PWM_IPW_SW_MINOR_VERSION_C != PWM_EMIOS_SW_MINOR_VERSION) || \
     (PWM_IPW_SW_PATCH_VERSION_C != PWM_EMIOS_SW_PATCH_VERSION))
    #error "Software Version Numbers of Pwm_Ipw.c and Pwm_eMios.h are different"
#endif



#if (PWM_IPW_VENDOR_ID_C != PWM_IPW_NOTIF_VENDOR_ID)
    #error "Pwm_Ipw.c and Pwm_Ipw_Notif.h have different vendor ids"
#endif

#if ((PWM_IPW_AR_RELEASE_MAJOR_VERSION_C    != PWM_IPW_NOTIF_AR_RELEASE_MAJOR_VERSION) || \
     (PWM_IPW_AR_RELEASE_MINOR_VERSION_C    != PWM_IPW_NOTIF_AR_RELEASE_MINOR_VERSION) || \
     (PWM_IPW_AR_RELEASE_REVISION_VERSION_C != PWM_IPW_NOTIF_AR_RELEASE_REVISION_VERSION))
    #error "AUTOSAR Version Numbers of Pwm_Ipw.c and Pwm_Ipw_Notif.h are different"
#endif

#if ((PWM_IPW_SW_MAJOR_VERSION_C != PWM_IPW_NOTIF_SW_MAJOR_VERSION) || \
     (PWM_IPW_SW_MINOR_VERSION_C != PWM_IPW_NOTIF_SW_MINOR_VERSION) || \
     (PWM_IPW_SW_PATCH_VERSION_C != PWM_IPW_NOTIF_SW_PATCH_VERSION))
    #error "Software Version Numbers of Pwm_Ipw.c and Pwm_Ipw_Notif.h are different"
#endif



/*===============================================================================================
*                          LOCAL TYPEDEFS (STRUCTURES, UNIONS, ENUMS)
===============================================================================================*/

#if ((PWM_PARAM_CHECK == STD_ON) && ((PWM_SET_PHASE_SHIFT_API == STD_ON) || (PWM_SET_PHASE_SHIFT_NO_UPDATE_API == STD_ON)))
/**
* @brief        Duty cycle 50%
*
*/
#define PWM_HALF_PERIOD_DUTY            ((uint16)0x4000U)
#endif



/*===============================================================================================
*                                       GLOBAL FUNCTIONS
===============================================================================================*/

#define PWM_START_SEC_CODE
/*
* @violates @ref Pwm_Ipw_c_REF_2 This violation is not fixed since the inclusion
*                of Pwm_MemMap.h is as per AUTOSAR requirement 
* @violates @ref Pwm_Ipw_c_REF_1 Pwm_MemMap.h is included after each section define
*                in order to set the current memory section as defined by AUTOSAR
*/
#include "Pwm_MemMap.h"


/**
* @brief        Pwm_Ipw_Init
* @details      This function call the supported IP initialization functions.
*
* @param        pIpConfig       Pointer to PWM top configuration structure
*
* @return       void
*
*/
FUNC(void, PWM_CODE) Pwm_Ipw_Init
(   
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{

    if (NULL_PTR != pIpConfig->peMiosIpConfig)
    {
        /* Call eMios IP initialize function */
        Pwm_eMios_Init(pIpConfig->peMiosIpConfig);
    }

}



/*===============================================================================================*/
#if (PWM_DE_INIT_API == STD_ON)
/**
* @brief        Pwm_Ipw_DeInit
* @details      This function call the supported IP de-initialization functions.
*
* @param        pIpConfig       Pointer to PWM top configuration structure
*
* @return       void
*
*/
FUNC(void, PWM_CODE) Pwm_Ipw_DeInit
(
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{

    if (NULL_PTR != pIpConfig->peMiosIpConfig)
    {
        /* Call eMios IP de-initialize function */
        Pwm_eMios_DeInit(pIpConfig->peMiosIpConfig);
    }

}
#endif /* PWM_DE_INIT_API */



/*===============================================================================================*/
#if (PWM_SET_DUTY_CYCLE_API == STD_ON)
/**
* @brief        Pwm_Ipw_SetDutyCycle
* @details      This function will call SetDutyCycle function for the corresponding IP of PwmChannel
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               u16DutyCycle    Duty cycle value 0x0000 for 0% ... 0x8000 for 100%
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       void
*
*/
FUNC(void, PWM_CODE) Pwm_Ipw_SetDutyCycle
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    VAR         (uint16,                        AUTOMATIC)                      u16DutyCycle,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{

    /* Call eMios IP function */
    Pwm_eMios_SetDutyCycle
    (
        (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
        u16DutyCycle,
#if ((PWM_SET_DUTY_CYCLE_NO_UPDATE_API == STD_ON) || (PWM_SET_PERIOD_AND_DUTY_NO_UPDATE_API == STD_ON) || (PWM_SET_PHASE_SHIFT_NO_UPDATE_API == STD_ON))
        PWM_EMIOS_UPDATE_ASYNCHRONOUS,
#endif
        pIpConfig->peMiosIpConfig
    );

}
#endif /* PWM_SET_DUTY_CYCLE_API */



/*===============================================================================================*/
#if (PWM_SET_PERIOD_AND_DUTY_API == STD_ON)
/**
* @brief        Pwm_Ipw_SetPeriodAndDuty
* @details      This function will call SetPeriodAndDuty function for the corresponding IP of PwmChannel
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               nPeriod         Period value for this channel
*               u16DutyCycle    Duty cycle value 0x0000 for 0% ... 0x8000 for 100%
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       void
*
*/
FUNC(void, PWM_CODE) Pwm_Ipw_SetPeriodAndDuty
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    VAR         (Pwm_PeriodType,                AUTOMATIC)                      nPeriod,
    VAR         (uint16,                        AUTOMATIC)                      u16DutyCycle,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{

    /* Call eMios IP function */
    Pwm_eMios_SetPeriodAndDuty
    (
        (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
        nPeriod,
        u16DutyCycle,
#if ((PWM_SET_DUTY_CYCLE_NO_UPDATE_API == STD_ON) || (PWM_SET_PERIOD_AND_DUTY_NO_UPDATE_API == STD_ON) || (PWM_SET_PHASE_SHIFT_NO_UPDATE_API == STD_ON))
        PWM_EMIOS_UPDATE_ASYNCHRONOUS,
#endif
        pIpConfig->peMiosIpConfig
    );
 
}
#endif /* PWM_SET_PERIOD_AND_DUTY_API */



/*===============================================================================================*/
#if (PWM_SET_OUTPUT_TO_IDLE_API == STD_ON)
/**
* @brief        Pwm_Ipw_SetOutputToIdle
* @details      This function will call SetOutputToIdle function for the corresponding IP of PwmChannel
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       void
*
*/
FUNC(void, PWM_CODE) Pwm_Ipw_SetOutputToIdle
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{

    /* Call eMios IP function */
    Pwm_eMios_SetOutputToIdle
    (
        (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
        pIpConfig->peMiosIpConfig
    );

}
#endif /* PWM_SET_OUTPUT_TO_IDLE_API */



/*===============================================================================================*/
#if (PWM_GET_OUTPUT_STATE_API == STD_ON)
/**
* @brief        Pwm_Ipw_GetOutputState
* @details      This function will call GetOutputState function for the corresponding IP of PwmChannel
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       Pwm_OutputStateType
*
*/
FUNC(Pwm_OutputStateType, PWM_CODE) Pwm_Ipw_GetOutputState
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{
    
    /** @brief  Store return value */
    VAR         (Pwm_OutputStateType,           AUTOMATIC)                      nRetVal = PWM_LOW;

    
    /* Call eMios IP function */
    nRetVal = Pwm_eMios_GetOutputState
              (
                (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
                pIpConfig->peMiosIpConfig
              );

    return nRetVal;
    
}
#endif /* PWM_GET_OUTPUT_STATE_API */



/*===============================================================================================*/
#if (PWM_NOTIFICATION_SUPPORTED == STD_ON)
/**
* @brief        Pwm_Ipw_DisableNotification
* @details      This function will call DisableNotification function for the corresponding IP of PwmChannel
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       void
*
*/
FUNC(void, PWM_CODE) Pwm_Ipw_DisableNotification
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{

    /* Call eMios IP function */
    Pwm_eMios_DisableNotification
    (
        (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
        pIpConfig->peMiosIpConfig
    );

}
#endif /* PWM_NOTIFICATION_SUPPORTED */



/*===============================================================================================*/
#if (PWM_NOTIFICATION_SUPPORTED == STD_ON)
/**
* @brief        Pwm_Ipw_EnableNotification
* @details      This function will call EnableNotification function for the corresponding IP of PwmChannel
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               eNotification   Notification edge type to be enabled
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       void
*
*/
FUNC(void, PWM_CODE) Pwm_Ipw_EnableNotification
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    VAR         (Pwm_EdgeNotificationType,      AUTOMATIC)                      eNotification,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{
    
    /* Call eMios IP function */
    Pwm_eMios_EnableNotification
    (
        (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
        eNotification,
        pIpConfig->peMiosIpConfig
    );

}
#endif /* PWM_NOTIFICATION_SUPPORTED */








/*===============================================================================================*/
#if (PWM_GET_CHANNEL_STATE_API == STD_ON)
/**
* @brief        Pwm_Ipw_GetChannelState
* @details      This function will call GetChannelState function for the corresponding IP of PwmChannel
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       uint16
*
*/
FUNC(uint16, PWM_CODE) Pwm_Ipw_GetChannelState
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{
    
    /** @brief  Store return value */
    VAR         (uint16,                        AUTOMATIC)                      u16DutyCycle = (uint16)0U;
    
    
    /* Call eMios IP function */
    u16DutyCycle = Pwm_eMios_GetChannelState((*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig);

    return u16DutyCycle;
    
}
#endif /* PWM_GET_CHANNEL_STATE */



/*===============================================================================================*/
#if (PWM_SET_CLOCK_MODE_API == STD_ON)
/**
* @brief        Pwm_Ipw_SetClockMode
* @details      This function will call SetClockMode function of all configured hardware eMIOS modules.
*
* @param        ePrescaler      Pre-scaler type
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       void
*
*/
FUNC(void, PWM_CODE) Pwm_Ipw_SetClockMode
(
    VAR         (Pwm_PrescalerType,             AUTOMATIC)                      ePrescaler,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{

    if (NULL_PTR != pIpConfig->peMiosIpConfig)
    {
        /* Call eMios IP function */
        Pwm_eMios_SetClockMode(ePrescaler, pIpConfig->peMiosIpConfig);
    }
    
}
#endif



/*===============================================================================================*/
#if (PWM_SET_COUNTER_BUS_API == STD_ON)
/**
* @brief        Pwm_Ipw_SetCounterBus
* @details      This function will change the counter bus of PWM channels running.
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               u32Bus          eMIOS bus to change to
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       void
*
*/
FUNC(void, PWM_CODE) Pwm_Ipw_SetCounterBus
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    VAR         (uint32,                        AUTOMATIC)                      u32Bus,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{

    /* Call eMIOS IP function */
    Pwm_eMios_SetCounterBus
    (
        (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
        pIpConfig->peMiosIpConfig,
        u32Bus
    );

}
#endif /* PWM_SET_COUNTER_BUS_API */



/*===============================================================================================*/
#if (PWM_SET_CHANNEL_OUTPUT_API == STD_ON)
/**
* @brief        Pwm_Ipw_SetChannelOutput
* @details      This function is useful to set the state of the PWM pin as requested
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               eState          State of the channel to change to
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       void
*
*/
FUNC(void, PWM_CODE) Pwm_Ipw_SetChannelOutput
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    VAR         (Pwm_StateType,                 AUTOMATIC)                      nState,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{

    /* Call eMIOS IP function */
    Pwm_eMios_SetChannelOutput
    (
        (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
        pIpConfig->peMiosIpConfig, 
        nState
    );

}
#endif /* PWM_SET_CHANNEL_OUTPUT_API */



/*===============================================================================================*/
#if (PWM_SET_PHASE_SHIFT_API == STD_ON)
/**
* @brief        This function set phase shift value and also force duty cycle to 50%.
* @details      This function only applies for channel in OPWMB, OPWM and OPWMT mode.
*               Pwm_SetPhaseShift allows to set both phase shift value and period,
*               the duty value is fixed to 50%.
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               nPeriod         Period value for this channel
*               u16PhaseShift   Phase shift value
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       void
*
*/
FUNC(void, PWM_CODE) Pwm_Ipw_SetPhaseShift
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    VAR         (Pwm_PeriodType,                AUTOMATIC)                      nPeriod,
    VAR         (uint16,                        AUTOMATIC)                      u16PhaseShift,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{

    /* Call eMIOS IP function */
    Pwm_eMios_SetPhaseShift
    (
        (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
        nPeriod,
        u16PhaseShift,
#if ((PWM_SET_DUTY_CYCLE_NO_UPDATE_API == STD_ON) || (PWM_SET_PERIOD_AND_DUTY_NO_UPDATE_API == STD_ON) || (PWM_SET_PHASE_SHIFT_NO_UPDATE_API == STD_ON))
        PWM_EMIOS_UPDATE_ASYNCHRONOUS,
#endif
        pIpConfig->peMiosIpConfig
    );

}
#endif /* PWM_SET_PHASE_SHIFT_API */



/*===============================================================================================*/
#if ((PWM_UPDATE_DUTY_SYNCHRONOUS == STD_ON) && (PWM_SET_DUTY_CYCLE_NO_UPDATE_API == STD_ON))
/**
* @brief        Pwm_Ipw_SetDutyCycle_NoUpdate
* @details      This function will call SetDutyCycle_NoUpdate function for the corresponding IP of PwmChannel
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               u16DutyCycle    Duty cycle value 0x0000 for 0% ... 0x8000 for 100%
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       void
*
*/
FUNC(void, PWM_CODE) Pwm_Ipw_SetDutyCycle_NoUpdate
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    VAR         (uint16,                        AUTOMATIC)                      u16DutyCycle,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{

    /* Call eMIOS IP function */
    Pwm_eMios_SetDutyCycle
    (
        (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
        u16DutyCycle,
        PWM_EMIOS_UPDATE_SYNCHRONOUS,
        pIpConfig->peMiosIpConfig
    );

}
#endif /* PWM_SET_DUTY_CYCLE_NO_UPDATE_API */



/*===============================================================================================*/
#if ((PWM_UPDATE_DUTY_SYNCHRONOUS == STD_ON) && (PWM_SET_PERIOD_AND_DUTY_NO_UPDATE_API == STD_ON))
/**
* @brief        Pwm_Ipw_SetPeriodAndDuty_NoUpdate
* @details      This function will call SetPeriodAndDuty_NoUpdate function for the corresponding IP of PwmChannel
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               nPeriod         Period value for this channel
*               u16DutyCycle    Duty cycle value 0x0000 for 0% ... 0x8000 for 100%
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       void
*
*/
FUNC(void, PWM_CODE) Pwm_Ipw_SetPeriodAndDuty_NoUpdate
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    VAR         (Pwm_PeriodType,                AUTOMATIC)                      nPeriod,
    VAR         (uint16,                        AUTOMATIC)                      u16DutyCycle,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{

    /* Call eMIOS IP function */
    Pwm_eMios_SetPeriodAndDuty
    (
        (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
        nPeriod,
        u16DutyCycle,
        PWM_EMIOS_UPDATE_SYNCHRONOUS,
        pIpConfig->peMiosIpConfig
    );
 
}
#endif /* PWM_SET_PERIOD_AND_DUTY_NO_UPDATE_API */



/*===============================================================================================*/
#if ((PWM_UPDATE_DUTY_SYNCHRONOUS == STD_ON) && (PWM_SET_PHASE_SHIFT_NO_UPDATE_API == STD_ON))
/**
* @brief        This function set phase shift value and also force duty cycle to 50% but not
*               update immediately.
* @details      This function only applies for channel in OPWMB, OPWM and OPWMT mode.
*               Pwm_SetPhaseShift allows to set both phase shift value and period,
*               the duty value is fixed to 50%.
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               nPeriod         Period value for this channel
*               u16PhaseShift   Phase shift value
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       void
*
*/
FUNC(void, PWM_CODE) Pwm_Ipw_SetPhaseShift_NoUpdate
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    VAR         (Pwm_PeriodType,                AUTOMATIC)                      nPeriod,
    VAR         (uint16,                        AUTOMATIC)                      u16PhaseShift,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{

    /* Call eMIOS IP function */
    Pwm_eMios_SetPhaseShift
    (
        (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
        nPeriod,
        u16PhaseShift,
        PWM_EMIOS_UPDATE_SYNCHRONOUS,
        pIpConfig->peMiosIpConfig
    );

}
#endif /* PWM_SET_PHASE_SHIFT_NO_UPDATE_API */



/*===============================================================================================*/
#if ((PWM_UPDATE_DUTY_SYNCHRONOUS == STD_ON) && (PWM_SYNC_UPDATE_API == STD_ON))
/**
* @brief        Implementation specific function to synchronous update.
* @details      This function is useful to synchronize multiple PWM channels.
*
* @param        u8ModuleIndex   eMIOS module index in PWM top configuration
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       void
*
*/
FUNC(void, PWM_CODE) Pwm_Ipw_SyncUpdate
(
    VAR         (uint8,                         AUTOMATIC)                      u8ModuleIndex,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{
    
    /* Call eMIOS IP function */
    Pwm_eMios_SyncUpdate
    (
        u8ModuleIndex,
        pIpConfig->peMiosIpConfig
    );

}
#endif /* PWM_SYNC_UPDATE_API */








/*===============================================================================================*/
#if ((PWM_PARAM_CHECK == STD_ON) && (PWM_NOTIFICATION_SUPPORTED == STD_ON))
/**
* @brief        Pwm_Ipw_ValidateNotification
* @details      This function will check validate of edge notification type with polarity
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               eNotification   Notification edge type to check if available
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       E_NOT_OK        Notification handler is not valid
*
*/
FUNC(Std_ReturnType, PWM_CODE) Pwm_Ipw_ValidateNotification
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    VAR         (Pwm_EdgeNotificationType,      AUTOMATIC)                      eNotification,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{
    
    /** @brief  Variable to store the value returned by the function */ 
    VAR         (Std_ReturnType,                AUTOMATIC)                      nRetVal = (Std_ReturnType)E_OK;

    
    /* Call eMios IP function */
    nRetVal = Pwm_eMios_ValidateNotification
              (
                (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
                eNotification
              );

    return nRetVal;
    
}
#endif



/*===============================================================================================*/
#if ((PWM_PARAM_CHECK == STD_ON) && ((PWM_SET_DUTY_CYCLE_API == STD_ON) || (PWM_SET_DUTY_CYCLE_NO_UPDATE_API == STD_ON)))
/**
* @brief        Pwm_Ipw_ValidateParamParamOffsetDuty
* @details      This function will check Offset parameter with default duty cycle of current channel
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               u16DutyCycle    Duty cycle value 0x0000 for 0% ... 0x8000 for 100%
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       uint8           Error ID
*
*/
FUNC(uint8, PWM_CODE) Pwm_Ipw_ValidateParamParamOffsetDuty
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    VAR         (uint16,                        AUTOMATIC)                      u16DutyCycle,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{
    
    /** @brief  Variable to store the value returned by the function */
    VAR         (uint8,                         AUTOMATIC)                      nRetVal = (uint8)0U;

    
    /* Call eMIOS IP function */
    nRetVal = Pwm_eMios_ValidateParamOffsetDuty
              (
                (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
                u16DutyCycle,
                pIpConfig->peMiosIpConfig
              );

    return nRetVal;
    
}
#endif



/*===============================================================================================*/
#if ((PWM_PARAM_CHECK == STD_ON) && (PWM_SET_TRIGGER_DELAY_API == STD_ON))
/**
* @brief        Pwm_Ipw_ValidateTriggerMode
* @details      This function will check validate operation mode of current channel to use 
*               trigger delay feature.
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       E_NOT_OK        Current channel mode is invalid
*
*/
FUNC(Std_ReturnType, PWM_CODE) Pwm_Ipw_ValidateTriggerMode
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{
    
    /** @brief  Variable to store the value returned by the function */ 
    VAR         (Std_ReturnType,                AUTOMATIC)                      nRetVal = (Std_ReturnType)E_OK;

    
    /* Call eMIOS IP function */
    nRetVal = Pwm_eMios_ValidateTriggerMode
              (
                (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
                pIpConfig->peMiosIpConfig
              );

    return nRetVal;
    
}
#endif



/*===============================================================================================*/
#if ((PWM_PARAM_CHECK == STD_ON) && (PWM_SET_COUNTER_BUS_API == STD_ON))
/**
* @brief        Pwm_Ipw_ValidateCounterBus
* @details      This function will validate of counter bus
*
* @param        uint32          Counter bus ID
*
* @return       Std_ReturnType  E_OK/E_NOT_OK
*
*/
FUNC(Std_ReturnType, PWM_CODE) Pwm_Ipw_ValidateCounterBus
(
    VAR         (uint32,                        AUTOMATIC)                      u32Bus,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{
    
    /** @brief  Variable to store the value returned by the function */ 
    VAR         (Std_ReturnType,                AUTOMATIC)                      nRetVal = (Std_ReturnType)E_OK;
    

    if (NULL_PTR != pIpConfig->peMiosIpConfig)
    {
        /* Call eMIOS IP function */
        nRetVal = Pwm_eMios_ValidateCounterBus(u32Bus);
    }

    return nRetVal;
    
}
#endif



/*===============================================================================================*/
#if (PWM_PARAM_CHECK == STD_ON)
/**
* @brief        Pwm_Ipw_ValidateParamOffset
* @details      This function will validate Offset parameter with default period and duty cycle
*               of all channels
*
* @param        pIpConfig       Pointer to PWM top configuration structure
*
* @return       uint8           Error ID
*
*/
FUNC(uint8, PWM_CODE) Pwm_Ipw_ValidateParamOffset
(
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{
    
    /** @brief  Variable to store the value returned by the function */
    VAR         (uint8,                         AUTOMATIC)                      u8RetVal = (uint8)0U;

    
    /* Call eMIOS IP function */
    u8RetVal = Pwm_eMios_ValidateParamOffset(pIpConfig->peMiosIpConfig);

    return u8RetVal;
    
}
#endif



/*===============================================================================================*/
#if ((PWM_PARAM_CHECK == STD_ON) && ((PWM_SET_PHASE_SHIFT_API == STD_ON) || (PWM_SET_PHASE_SHIFT_NO_UPDATE_API == STD_ON)))
/**
* @brief        Pwm_Ipw_ValidateChannelSetPhaseShift
* @details      This function will check given channel with phase shift supported
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       Std_ReturnType  E_NOT_OK - phase shift is not supported this channel
*
*/
FUNC(Std_ReturnType, PWM_CODE) Pwm_Ipw_ValidateChannelSetPhaseShift
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{

    /** @brief  Variable to store the value returned by the function */
    VAR         (Std_ReturnType,                AUTOMATIC)                      nRetVal = (Std_ReturnType)E_OK;


    /* Call eMIOS IP function */
    nRetVal = Pwm_eMios_ValidateChannelSetPhaseShift
              (
                (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
                pIpConfig->peMiosIpConfig
              );
    
    return nRetVal;

}
#endif /* PWM_PARAM_CHECK && (PWM_SET_PHASE_SHIFT_API || PWM_SET_PHASE_SHIFT_NO_UPDATE_API) */



/*===============================================================================================*/
#if ((PWM_PARAM_CHECK == STD_ON) && ((PWM_SET_PHASE_SHIFT_API == STD_ON) || (PWM_SET_PHASE_SHIFT_NO_UPDATE_API == STD_ON)))
/**
* @brief        Pwm_Ipw_ValidateParamsPhaseShift
* @details      This function will check phase shift value, has to be equal or lower than duty 50%
*
* @param        u16PhaseShift   Phase shift value
*
* @return       Std_ReturnType  E_NOT_OK - synchronization is not supported this channel
*
*/
FUNC(Std_ReturnType, PWM_CODE) Pwm_Ipw_ValidateParamsPhaseShift
(
    VAR         (uint16,                        AUTOMATIC)                      u16PhaseShift
)
{

    /** @brief  Variable to store the value returned by the function */
    VAR         (Std_ReturnType,                AUTOMATIC)                      nRetVal = (Std_ReturnType)E_OK;


    if (PWM_HALF_PERIOD_DUTY < u16PhaseShift)
    {
        nRetVal = (Std_ReturnType)E_NOT_OK;
    }

    return nRetVal;

}
#endif /* PWM_PARAM_CHECK && (PWM_SET_PHASE_SHIFT_API || PWM_SET_PHASE_SHIFT_NO_UPDATE_API) */



/*===============================================================================================*/
#if ((PWM_PARAM_CHECK == STD_ON) && ((PWM_SET_DUTY_CYCLE_NO_UPDATE_API == STD_ON) || (PWM_SET_PERIOD_AND_DUTY_NO_UPDATE_API == STD_ON) || (PWM_SET_PHASE_SHIFT_NO_UPDATE_API == STD_ON)))
/**
* @brief        Pwm_Ipw_ValidateChannelSync
* @details      This function will check given channel with synchronization supported
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       Std_ReturnType  E_NOT_OK - synchronization is not supported this channel
*
*/
FUNC(Std_ReturnType, PWM_CODE) Pwm_Ipw_ValidateChannelSync
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{

    /** @brief  Variable to store the value returned by the function */
    VAR         (Std_ReturnType,                AUTOMATIC)                      nRetVal = (Std_ReturnType)E_OK;


    /* Call eMIOS IP function */
    nRetVal = Pwm_eMios_ValidateChannelSync
              (
                (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig,
                pIpConfig->peMiosIpConfig
              );

    return nRetVal;

}
#endif /* PWM_PARAM_CHECK && (PWM_SET_DUTY_CYCLE_NO_UPDATE_API || PWM_SET_PERIOD_AND_DUTY_NO_UPDATE_API) */








/*===============================================================================================*/
#if ((PWM_PARAM_CHECK == STD_ON) && ((PWM_SET_PERIOD_AND_DUTY_API == STD_ON) || (PWM_SET_PERIOD_AND_DUTY_NO_UPDATE_API == STD_ON)))
/**
* @brief        Pwm_Ipw_GetMaxPeriodValue
* @details      This function will calculate the maximum period value supported by hardware
*
* @param        nChannelNumber  PWM logical channel ID in top configuration structure
*               nPeriod         Period value
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       uint32
*
*/
FUNC(uint32, PWM_CODE) Pwm_Ipw_GetMaxPeriodValue
(
    VAR         (Pwm_ChannelType,               AUTOMATIC)                      nChannelNumber,
    CONSTP2CONST(Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{
    
    /** @brief  Store return value */
    VAR         (uint32,                        AUTOMATIC)                      u32RetVal = (uint32)0xFFFFU;
    
    
    /* Call eMIOS IP function */
    u32RetVal = Pwm_eMios_GetMaxPeriodValue
                (
                    (*pIpConfig->pIpChannelsConfig)[nChannelNumber].u8IdxChannelConfig, 
                    pIpConfig->peMiosIpConfig
                );

    return u32RetVal;
    
}
#endif








/*===============================================================================================*/
#if (PWM_POWER_STATE_SUPPORTED == STD_ON)
/**
* @brief        Pwm_Ipw_ValidateIdleState
* @details      This function will call ValidateIdleState function of all configured hardware eMIOS modules
*
* @param        pIpConfig       Pointer to PWM top configuration structure
*
* @return       Std_ReturnType  Idle state status
*
*/
FUNC(Std_ReturnType, PWM_CODE) Pwm_Ipw_ValidateIdleState
(
    P2CONST     (Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig
)
{
    
    /** @brief  Variable to store the value returned by the function */ 
    VAR         (Std_ReturnType,                AUTOMATIC)                      nRetVal = (Std_ReturnType)E_OK;


    if (NULL_PTR != pIpConfig->peMiosIpConfig)
    {
        /* Call eMios IP function */
        nRetVal = Pwm_eMios_ValidateIdleState(pIpConfig->peMiosIpConfig);
    }

    return nRetVal;
    
}
#endif /* PWM_POWER_STATE_SUPPORTED */



/*===============================================================================================*/
#if (PWM_POWER_STATE_SUPPORTED == STD_ON)
/**
* @brief        Pwm_Ipw_SetPowerState
* @details      This function will call SetPowerState function of all configured hardware eMIOS modules
*
* @param        nPowerState     Target power mode
*               pIpConfig       Pointer to PWM top configuration structure
*
* @return       void
*
*/
FUNC(void, PWM_CODE) Pwm_Ipw_SetPowerState
(
    P2CONST     (Pwm_IpConfigType,              AUTOMATIC,  PWM_APPL_CONST)     pIpConfig,
    VAR         (Pwm_PowerStateType,            AUTOMATIC)                      nPowerState
)
{

    if (NULL_PTR != pIpConfig->peMiosIpConfig)
    {
        /* Call eMios IP function */
        Pwm_eMios_SetPowerState(pIpConfig->peMiosIpConfig, nPowerState);
    }
    
}
#endif /* PWM_POWER_STATE_SUPPORTED */


#define PWM_STOP_SEC_CODE
/*
* @violates @ref Pwm_Ipw_c_REF_2 This violation is not fixed since the inclusion
*                of Pwm_MemMap.h is as per AUTOSAR requirement 
* @violates @ref Pwm_Ipw_c_REF_1 Pwm_MemMap.h is included after each section define
*                in order to set the current memory section as defined by AUTOSAR
*/
#include "Pwm_MemMap.h"



#ifdef __cplusplus
}
#endif

/** @} */
