/*!
* @file     Pwm.c
*
* @version  1.0.0
*
* @brief    Code file of AUTOSAR PWM driver
*
* @attention
*
* Project Name      : AUTOSAR MCAL
*
* Platform          : Arm
*
* Autosar Standard  : Classic Platform 4.4.0
*
* Compiled Version  : G32A10xx_MCAL_1_0_0_01-Otc-25
*
* Copyright (C) 2026 Geehy Semiconductor
*
* You may not use this file except in compliance with the
* GEEHY COPYRIGHT NOTICE (Geehy Semiconductor Software License Agreement).
*
* The program is only for reference, which is distributed in the hope
* that it will be usefull and instructional for customers to develop
* their software. Unless required by applicable law or agreed to in
* writing, the program is distributed on an "AS IS" BASIS, WITHOUT
* ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
* See the Geehy Semiconductor Software License Agreement for the governing permissions
* and limitations under the License.
*/

#ifdef __cplusplus
extern "C"{
#endif

#include "Pwm_Tmr.h"
#include "Pwm_Notif.h"
#if ((STD_ON == PWM_LOW_POWER_STATE_ENABLE) || (STD_ON == PWM_DEV_ERROR_DETECT))
    #include "Det.h"
#endif

/** @addtogroup G32A10xx_StdPeriphDriver
  @{
*/

/** @defgroup PWM_Driver
  * @brief PWM driver modules
  @{
*/

/** @defgroup PWM_Macros
  @{
*/
/**************************************************************************
                  VENDOR ID & AUTOSAR VERSION INFO
**************************************************************************/
/** Vendor ID (vendorId) of the dedicated implementation of this module according to the AUTOSAR vendor list. */
#define PWM_VENDOR_ID                      0x00C1U
/** Major version number of AUTOSAR release on which the appropriate implementation is based on. */
#define PWM_AR_RELEASE_MAJOR_VERSION       0x04U
/** Minor version number of AUTOSAR release on which the appropriate implementation is based on. */
#define PWM_AR_RELEASE_MINOR_VERSION       0x04U
/** Revision version number of AUTOSAR release on which the appropriate implementation is based on. */
#define PWM_AR_RELEASE_REVISION_VERSION    0x00U
/** Major version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define PWM_SW_MAJOR_VERSION               0x01U
/** Minor version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define PWM_SW_MINOR_VERSION               0x00U
/** Patch level version number of the vendor specific implementation of the module. The numbering is vendor specific. */
#define PWM_SW_PATCH_VERSION               0x00U

/**@} end of group PWM_Macros */

/**************************************************************************
                    VERSION INFOMATION VERIFICATION
**************************************************************************/
/* Make sure the vendor id is the same between Pwm.c and Pwm_Tmr.h */
#if (PWM_VENDOR_ID != PWM_TMR_H_VENDOR_ID)
    #error "Vendor id mismatch between Pwm.c and Pwm_Tmr.h " 
#endif
/* Make sure the AUTOSAR major version number is the same between Pwm.c and Pwm_Tmr.h */
#if (PWM_AR_RELEASE_MAJOR_VERSION != PWM_TMR_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR Major Version Number mismatch between Pwm.c and Pwm_Tmr.h "
#endif
/* Make sure the AUTOSAR minor version number is the same between Pwm.c and Pwm_Tmr.h */
#if (PWM_AR_RELEASE_MINOR_VERSION != PWM_TMR_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Number mismatch between Pwm.c and Pwm_Tmr.h "
#endif
/* Make sure the AUTOSAR revision version number is the same between Pwm.c and Pwm_Tmr.h */
#if (PWM_AR_RELEASE_REVISION_VERSION != PWM_TMR_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR Revision Version Number mismatch between Pwm.c and Pwm_Tmr.h "
#endif
/* Make sure the software major version number is the same between Pwm.c and Pwm_Tmr.h */
#if (PWM_SW_MAJOR_VERSION != PWM_TMR_H_SW_MAJOR_VERSION)
    #error "Software Major Version Number mismatch between Pwm.c and Pwm_Tmr.h "
#endif
/* Make sure the software minor version number is the same between Pwm.c and Pwm_Tmr.h */
#if (PWM_SW_MINOR_VERSION != PWM_TMR_H_SW_MINOR_VERSION)
    #error "Software Minor Version Number mismatch between Pwm.c and Pwm_Tmr.h "
#endif
/* Make sure the software patch version number is the same between Pwm.c and Pwm_Tmr.h */
#if (PWM_SW_PATCH_VERSION != PWM_TMR_H_SW_PATCH_VERSION)
    #error "Software Patch Version Number mismatch between Pwm.c and Pwm_Tmr.h "
#endif

/* Make sure the vendor id is the same between Pwm.c and Pwm_Notif.h */
#if (PWM_VENDOR_ID != PWM_NOTIF_H_VENDOR_ID)
    #error "Vendor id mismatch between Pwm.c and Pwm_Notif.h " 
#endif
/* Make sure the AUTOSAR major version number is the same between Pwm.c and Pwm_Notif.h */
#if (PWM_AR_RELEASE_MAJOR_VERSION != PWM_NOTIF_H_AR_RELEASE_MAJOR_VERSION)
    #error "AUTOSAR Major Version Number mismatch between Pwm.c and Pwm_Notif.h "
#endif
/* Make sure the AUTOSAR minor version number is the same between Pwm.c and Pwm_Notif.h */
#if (PWM_AR_RELEASE_MINOR_VERSION != PWM_NOTIF_H_AR_RELEASE_MINOR_VERSION)
    #error "AUTOSAR Minor Version Number mismatch between Pwm.c and Pwm_Notif.h "
#endif
/* Make sure the AUTOSAR revision version number is the same between Pwm.c and Pwm_Notif.h */
#if (PWM_AR_RELEASE_REVISION_VERSION != PWM_NOTIF_H_AR_RELEASE_REVISION_VERSION)
    #error "AUTOSAR Revision Version Number mismatch between Pwm.c and Pwm_Notif.h "
#endif
/* Make sure the software major version number is the same between Pwm.c and Pwm_Notif.h */
#if (PWM_SW_MAJOR_VERSION != PWM_NOTIF_H_SW_MAJOR_VERSION)
    #error "Software Major Version Number mismatch between Pwm.c and Pwm_Notif.h "
#endif
/* Make sure the software minor version number is the same between Pwm.c and Pwm_Notif.h */
#if (PWM_SW_MINOR_VERSION != PWM_NOTIF_H_SW_MINOR_VERSION)
    #error "Software Minor Version Number mismatch between Pwm.c and Pwm_Notif.h "
#endif
/* Make sure the software patch version number is the same between Pwm.c and Pwm_Notif.h */
#if (PWM_SW_PATCH_VERSION != PWM_NOTIF_H_SW_PATCH_VERSION)
    #error "Software Patch Version Number mismatch between Pwm.c and Pwm_Notif.h "
#endif

#ifdef ENABLE_INTERMODULE_MCAL_CHECK
    #if (STD_ON == PWM_DEV_ERROR_DETECT)
        /* Make sure the AUTOSAR major version number is the same between Pwm.c and Det.h */
        #if (PWM_AR_RELEASE_MAJOR_VERSION != DET_H_AR_RELEASE_MAJOR_VERSION)
            #error "AUTOSAR Major Version Number mismatch between Pwm.c and Det.h "
        #endif
        /* Make sure the AUTOSAR minor version number is the same between Pwm.c and Det.h */
        #if (PWM_AR_RELEASE_MINOR_VERSION != DET_H_AR_RELEASE_MINOR_VERSION)
            #error "AUTOSAR Minor Version Number mismatch between Pwm.c and Det.h "
        #endif
    #endif
#endif

/**************************************************************************
                    LOCAL VARIABLE
**************************************************************************/
#if (STD_ON == PWM_LOW_POWER_STATE_ENABLE)
    #define PWM_START_SEC_VAR_NO_INIT_UNSPECIFIED
    #include "Pwm_MemMap.h"
    
    /** @defgroup PWM_Variable
      @{
    */
    
    /** indicate current pwm power state */
    static VAR(Pwm_PowerStateType, PWM_VAR) s_pwmCurrentPowerState;
    /** indicate target pwm power state */
    static VAR(Pwm_PowerStateType, PWM_VAR) s_pwmTargetPowerState;
    
    /**@} end of group PWM_Variable */
    
    #define PWM_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
    #include "Pwm_MemMap.h"
#endif

#define PWM_START_SEC_VAR_INIT_UNSPECIFIED
#include "Pwm_MemMap.h"

/** @defgroup PWM_Variable
  @{
*/

/** used to point the pwm configuration structure */
static P2CONST(Pwm_ConfigType, PWM_VAR, PWM_APPL_CONST) s_pwmCfgPtr = NULL_PTR;
#if (STD_ON == PWM_DEV_ERROR_DETECT)
/** indicate pwm module state */
static VAR(Pwm_ModuleStateType, PWM_VAR) s_pwmModuleState = PWM_MODULE_STATE_UNINIT;
#endif

/**@} end of group PWM_Variable */

#define PWM_STOP_SEC_VAR_INIT_UNSPECIFIED
#include "Pwm_MemMap.h"

/**************************************************************************
                    FUNCTION DECLARATION
**************************************************************************/
#define PWM_START_SEC_CODE
#include "Pwm_MemMap.h"

/** @defgroup PWM_Fuctions
  @{
*/

#if (STD_ON == PWM_DEV_ERROR_DETECT)

#if (STD_ON == PWM_SOFTWARE_RESET_COUNTER)
LOCAL_INLINE  FUNC(Std_ReturnType, PWM_CODE) Pwm_CheckPwmInstanceId(VAR(uint8, AUTOMATIC) InstanceId,
                                                                    VAR(uint8, AUTOMATIC) ApiId);
#endif

#if ((STD_ON == PWM_SET_DUTY_CYCLE_API) || (STD_ON == PWM_SET_DUTY_CYCLE_SWSYNC))
LOCAL_INLINE  FUNC(Std_ReturnType, PWM_CODE) Pwm_CheckSetDutyCyclePara(VAR(uint16, AUTOMATIC) DutyCycle, 
                                                                       VAR(uint8, AUTOMATIC)  ApiId);
#endif

#if ((STD_ON == PWM_SET_PERIOD_AND_DUTY_API) || (STD_ON == PWM_SET_PERIOD_AND_DUTY_SWSYNC))
LOCAL_INLINE  FUNC(Std_ReturnType, PWM_CODE) Pwm_CheckSetPeriodAndDutyPara(VAR(Pwm_ChannelClassType, AUTOMATIC) ChClass,
                                                                           VAR(Pwm_PeriodType, AUTOMATIC) Period,
                                                                           VAR(uint16, AUTOMATIC) DutyCycle,
                                                                           VAR(uint8, AUTOMATIC) ApiId);
#endif

#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
LOCAL_INLINE  FUNC(Std_ReturnType, PWM_CODE) Pwm_CheckPwmChNotifyCfg(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber);
#endif

LOCAL_INLINE  FUNC(Std_ReturnType, PWM_CODE) Pwm_CheckInitApiPara(P2CONST(Pwm_ConfigType,AUTOMATIC,PWM_APPL_CONST) ptr);

LOCAL_INLINE  FUNC(Std_ReturnType, PWM_CODE) Pwm_CheckPwmModuleState(VAR(uint8, AUTOMATIC) ApiId);

LOCAL_INLINE  FUNC(void, PWM_CODE) Pwm_SetModuleStateBeforeExitApi(VAR(Std_ReturnType, AUTOMATIC) CheckResult,
                                                                   VAR(uint8, AUTOMATIC) ApiId);
#endif

#if (STD_ON == PWM_LOW_POWER_STATE_ENABLE)
LOCAL_INLINE FUNC(Std_ReturnType, PWM_CODE) Pwm_CheckChIdleState
                                            (P2CONST(Pwm_IpCfgType, AUTOMATIC, PWM_APPL_CONST) ipCfgPtr);
#endif

#if (STD_ON == PWM_DEV_ERROR_DETECT)
#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_GET_OUTPUT_STATE_API)         || \
     (STD_ON == PWM_GET_CHANNEL_DUTYCYCLE)   || (STD_ON == PWM_NOTIFICATION_SUPPORTED)       || \
     (STD_ON == PWM_SET_PERIOD_AND_DUTY_SWSYNC)   || (STD_ON == PWM_SET_DUTY_CYCLE_SWSYNC))
LOCAL_INLINE  FUNC(Std_ReturnType, PWM_CODE) Pwm_CheckChIdAndSuitableForApi(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber,
                                                                     VAR(uint8, AUTOMATIC) ApiId);
#endif
#endif

/**************************************************************************
                    LOCAL FUNCTION
**************************************************************************/
#if (STD_ON == PWM_DEV_ERROR_DETECT)

#if(STD_ON == PWM_SOFTWARE_RESET_COUNTER)
/*!
* @brief         This function is used to check Pwm instance id which can report PWM_E_INSTANCE_ID error.
*
* @param[in]     InstanceId    -pwm instance id
* @param[in]     ApiId         -API service id
* @param[out]    None
* @param[in,out] None
*
* @retval        Std_ReturnType:E_OK/E_NOT_OK
*/
LOCAL_INLINE  FUNC(Std_ReturnType, PWM_CODE) Pwm_CheckPwmInstanceId(VAR(uint8, AUTOMATIC) InstanceId,
                                                                    VAR(uint8, AUTOMATIC) ApiId)
{
    VAR(Std_ReturnType, AUTOMATIC) ret = (Std_ReturnType)((PWM_HW_MODULE_CONFIG_NUM <= InstanceId) ? E_NOT_OK : E_OK );

    if((Std_ReturnType)E_NOT_OK == ret)
    {
        (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX, (uint8)ApiId, (uint8)PWM_E_INSTANCE_ID);
    }
    else
    {
        /* do nothing */
    }

    return ret;
}
#endif

#if ((STD_ON == PWM_SET_DUTY_CYCLE_API) || (STD_ON == PWM_SET_DUTY_CYCLE_SWSYNC))
/*!
* @brief         This function is used to check Pwm_SetDutyCycle() dutycycle
*                parameter which can report PWM_E_DUTYCYCLE_BEYOND_SCOPE error.
*
* @param[in]     DutyCycle           -API dutycycle parameter
* @param[in]     ApiId               -API service id
* @param[out]    None
* @param[in,out] None
*
* @retval        Std_ReturnType:E_OK/E_NOT_OK
*/
LOCAL_INLINE  FUNC(Std_ReturnType, PWM_CODE) Pwm_CheckSetDutyCyclePara(VAR(uint16, AUTOMATIC) DutyCycle,
                                                                       VAR(uint8, AUTOMATIC) ApiId)
{
    VAR(Std_ReturnType, AUTOMATIC) ret = (Std_ReturnType)((DutyCycle > (uint16)PWM_DUTY_CYCLE_FULL) ? E_NOT_OK : E_OK );

    if((Std_ReturnType)E_NOT_OK == ret)
    {
        (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX,
                              (uint8)ApiId, (uint8)PWM_E_DUTYCYCLE_BEYOND_SCOPE);
    }
    else
    {
        /* do nothing */
    }

    return ret;
}
#endif

#if ((STD_ON == PWM_SET_PERIOD_AND_DUTY_API) || (STD_ON == PWM_SET_PERIOD_AND_DUTY_SWSYNC))
/*!
* @brief         This function is used to check Pwm_SetPeriodAndDuty() 
*                parameter which can report PWM_E_PERIOD_UNCHANGEABLE, PWM_E_PERIOD_ID and
*                PWM_E_DUTYCYCLE_BEYOND_SCOPE error.
*
* @param[in]     ChClass             -channel class
* @param[in]     Period              -target period value
* @param[in]     DutyCycle           -target duty cycle value
* @param[in]     ApiId               -API service id
* @param[out]    None
* @param[in,out] None
*
* @retval        Std_ReturnType:E_OK/E_NOT_OK
*/
LOCAL_INLINE  FUNC(Std_ReturnType, PWM_CODE) Pwm_CheckSetPeriodAndDutyPara(VAR(Pwm_ChannelClassType, AUTOMATIC) ChClass,
                                                                           VAR(Pwm_PeriodType, AUTOMATIC) Period,
                                                                           VAR(uint16, AUTOMATIC) DutyCycle,
                                                                           VAR(uint8, AUTOMATIC) ApiId)
{
    VAR(Std_ReturnType, AUTOMATIC) ret = (Std_ReturnType)E_OK;

    if(PWM_VARIABLE_PERIOD != ChClass)
    {
        (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX, (uint8)ApiId, (uint8)PWM_E_PERIOD_UNCHANGEABLE);
        ret = (Std_ReturnType)E_NOT_OK;
    }
    else
    {
        if ((uint32)Period > (uint32)0xFFFEU)
        {
            (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX, (uint8)ApiId, (uint8)PWM_E_PERIOD_ID);
            ret = (Std_ReturnType)E_NOT_OK;
        }
        else
        {
            if (DutyCycle > (uint16)PWM_DUTY_CYCLE_FULL)
            {
                (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX,
                                      (uint8)ApiId, (uint8)PWM_E_DUTYCYCLE_BEYOND_SCOPE);
                ret = (Std_ReturnType)E_NOT_OK;
            }
            else
            {
                /* do nothing */
            }
        }
    }

    return ret;
}
#endif

#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
/*!
* @brief         This function is used to check Pwm channel notification configuration which can report 
*                PWM_E_NOTIFICATION_POINTER_IS_NULL error.
*
* @param[in]     ChannelNumber    -channel id
* @param[out]    None
* @param[in,out] None
*
* @retval        Std_ReturnType:E_OK/E_NOT_OK
*/
LOCAL_INLINE  FUNC(Std_ReturnType, PWM_CODE) Pwm_CheckPwmChNotifyCfg(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber)
{
    VAR(Std_ReturnType, AUTOMATIC) ret = (Std_ReturnType)E_OK;

    if(NULL_PTR == ((*s_pwmCfgPtr->pChClassNotifyPtr)[ChannelNumber].pwmChNotifyPtr))
    {
        (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX,
                              (uint8)PWM_ENABLENOTIFICATION_SERVICE_ID, (uint8)PWM_E_NOTIFICATION_POINTER_IS_NULL);
        ret = (Std_ReturnType)E_NOT_OK;
    }
    else
    {
        /* do nothing */
    }

    return ret;
}
#endif

/*!
* @brief         This function is used to check Pwm_Init() parameter which can report PWM_E_INIT_FAILED error.
*
* @param[in]     ptr        -Pwm_Init() parameter
* @param[out]    None
* @param[in,out] None
*
* @retval        Std_ReturnType:E_OK/E_NOT_OK
*/
LOCAL_INLINE FUNC(Std_ReturnType, PWM_CODE) Pwm_CheckInitApiPara(P2CONST(Pwm_ConfigType,AUTOMATIC,PWM_APPL_CONST) ptr)
{
    VAR(Std_ReturnType, AUTOMATIC) ret = (Std_ReturnType)((NULL_PTR == ptr) ? E_NOT_OK : E_OK );

    if((Std_ReturnType)E_NOT_OK == ret)
    {
        (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX,
                              (uint8)PWM_INIT_SERVICE_ID, (uint8)PWM_E_INIT_FAILED);
    }
    else
    {
        /* do nothing */
    }

    return ret;
}

/*!
* @brief         This function is used to check pwm module state which can report 
*                PWM_E_UNINIT and PWM_E_ALREADY_INITIALIZED error.
*
* @param[in]     ApiId       -API service id
* @param[out]    None
* @param[in,out] None
*
* @retval        Std_ReturnType:E_OK/E_NOT_OK
*/
LOCAL_INLINE FUNC(Std_ReturnType, PWM_CODE) Pwm_CheckPwmModuleState(VAR(uint8, AUTOMATIC) ApiId)
{
    VAR(Std_ReturnType, AUTOMATIC) ret = (Std_ReturnType)E_OK;

    if(PWM_MODULE_STATE_UNINIT == s_pwmModuleState)
    {
        ret = (Std_ReturnType)(((uint8)PWM_INIT_SERVICE_ID != ApiId) ? E_NOT_OK : E_OK );
    
        if ((Std_ReturnType)E_NOT_OK == ret)
        {
            (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX, (uint8)ApiId, (uint8)PWM_E_UNINIT);
        }
        else
        {
            /* do nothing */
        }
    }
    else
    {
        ret = (Std_ReturnType)(((uint8)PWM_INIT_SERVICE_ID == ApiId) ? E_NOT_OK : E_OK );
    
        if ((Std_ReturnType)E_NOT_OK == ret)
        {
            (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX, (uint8)ApiId,(uint8)PWM_E_ALREADY_INITIALIZED);
        }
        else
        {
            /* do nothing */
        }
    }

    return ret;
}

/*!
* @brief         This function is used to set pwm module state before exit API.
*
* @param[in]     CheckResult        -check result
* @param[in]     ApiId              -API service id
* @param[out]    None
* @param[in,out] None
*
* @retval        None
*/
LOCAL_INLINE  FUNC(void, PWM_CODE) Pwm_SetModuleStateBeforeExitApi(VAR(Std_ReturnType, AUTOMATIC) CheckResult,
                                                                   VAR(uint8, AUTOMATIC) ApiId)
{
    if ((Std_ReturnType)E_OK == CheckResult)
    {
        s_pwmModuleState = ((uint8)PWM_DEINIT_SERVICE_ID == ApiId) ? PWM_MODULE_STATE_UNINIT : PWM_MODULE_STATE_IDLE;
    }
    else
    {
        /* do nothing */
    }
}

#endif

#if (STD_ON == PWM_LOW_POWER_STATE_ENABLE)
/*!
* @brief         This function is used to check whether pwm channel is in idle state.
*
* @param[in]     ipCfgPtr     -point to channel Pwm_IpCfgType configuration struct
* @param[out]    None
* @param[in,out] None
*
* @retval        Std_ReturnType:E_OK/E_NOT_OK
*/
LOCAL_INLINE  FUNC(Std_ReturnType, PWM_CODE) Pwm_CheckChIdleState(P2CONST(Pwm_IpCfgType, AUTOMATIC, PWM_APPL_CONST) ipCfgPtr)
{
    VAR(Std_ReturnType, AUTOMATIC) ret = (Std_ReturnType)E_OK;

    if (NULL_PTR != ipCfgPtr->pTmrIpCfgPtr)
    {
        ret = Pwm_Tmr_CheckChIdleState();
    }
    else
    {
        /* do nothing */
    }

    return ret;
}
#endif

#if (STD_ON == PWM_DEV_ERROR_DETECT)
#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_GET_OUTPUT_STATE_API)         || \
     (STD_ON == PWM_GET_CHANNEL_DUTYCYCLE)   || (STD_ON == PWM_NOTIFICATION_SUPPORTED)       || \
     (STD_ON == PWM_SET_PERIOD_AND_DUTY_SWSYNC)   || (STD_ON == PWM_SET_DUTY_CYCLE_SWSYNC))
/*!
* @brief         This function is used to check pwm channel whether suitable for a API which can report 
*                PWM_E_UNINIT, PWM_E_PARAM_CHANNEL error.
*
* @param[in]     ChannelNumber    -channel id
* @param[in]     ApiId            -API service id
* @param[out]    None
* @param[in,out] None
*
* @retval        Std_ReturnType:E_OK/E_NOT_OK
*/
LOCAL_INLINE FUNC(Std_ReturnType, PWM_CODE) Pwm_CheckChIdAndSuitableForApi(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber,
                                                                     VAR(uint8, AUTOMATIC) ApiId)
{
    VAR(Std_ReturnType, AUTOMATIC) ret = (Std_ReturnType)E_OK;

    if (PWM_MODULE_STATE_UNINIT == s_pwmModuleState)
    {
        ret = (Std_ReturnType)E_NOT_OK;
        (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX, (uint8)ApiId, (uint8)PWM_E_UNINIT);
    }
    else
    {
        if (ChannelNumber >= s_pwmCfgPtr->cfgChNumber)
        {
            ret = (Std_ReturnType)E_NOT_OK;
            (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX, (uint8)ApiId, (uint8)PWM_E_PARAM_CHANNEL);
        }
        else
        {
            /* do nothing */
        }
    }

    return ret;
}
#endif 
#endif

/**************************************************************************
                    GLOBAL FUNCTION
**************************************************************************/
/*!
* @brief         Initializes the pwm driver with configurations parameters.
*
* @param[in]     ConfigPtr      -pointer to the configuration parameters
* @param[out]    None
* @param[in,out] None
*
* @retval        None
*/
FUNC(void, PWM_CODE) Pwm_Init(P2CONST(Pwm_ConfigType, AUTOMATIC, PWM_APPL_CONST) ConfigPtr)
{

#if (STD_ON == PWM_DEV_ERROR_DETECT)
    VAR(Std_ReturnType, AUTOMATIC) checkResult = E_NOT_OK;
    /* check pwm module state */
    checkResult = Pwm_CheckPwmModuleState((uint8)PWM_INIT_SERVICE_ID);
    if((Std_ReturnType)E_OK == checkResult)
    {
#endif
        s_pwmCfgPtr = ConfigPtr;
#if (STD_ON == PWM_DEV_ERROR_DETECT)
        checkResult = Pwm_CheckInitApiPara(ConfigPtr);
        if((Std_ReturnType)E_OK == checkResult)
        {
#endif
            if (NULL_PTR != (&s_pwmCfgPtr->pwmIpCfg)->pTmrIpCfgPtr)
            {
                Pwm_Tmr_Init((&s_pwmCfgPtr->pwmIpCfg)->pTmrIpCfgPtr);
            }
            else
            {
                /* do nothing */
            }
#if (STD_ON == PWM_LOW_POWER_STATE_ENABLE)
            /* initialize pwm power state */
            s_pwmCurrentPowerState = PWM_FULL_POWER;
            s_pwmTargetPowerState = PWM_NODEFINE_POWER;
#endif
#if (STD_ON == PWM_DEV_ERROR_DETECT)
        }
        else
        {
            /* do nothing */
        }
#endif
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    }
    else
    {
        /* do nothing */
    }
    Pwm_SetModuleStateBeforeExitApi(checkResult, (uint8)PWM_INIT_SERVICE_ID);
#endif
}

#if (STD_ON == PWM_DE_INIT_API)
/*!
* @brief         De-initializes the pwm driver.
*
* @param[in]     None
* @param[out]    None
* @param[in,out] None
*
* @retval        None
*/
FUNC(void, PWM_CODE) Pwm_DeInit(void)
{
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    VAR(Std_ReturnType, AUTOMATIC) checkResult = Pwm_CheckPwmModuleState((uint8)PWM_DEINIT_SERVICE_ID);

    if((Std_ReturnType)E_OK == checkResult)
#endif 
    {
        if (NULL_PTR != (&s_pwmCfgPtr->pwmIpCfg)->pTmrIpCfgPtr)
        {
            Pwm_Tmr_DeInit((&s_pwmCfgPtr->pwmIpCfg)->pTmrIpCfgPtr);
        }
        else
        {
            /* do nothing */
        }

        s_pwmCfgPtr = NULL_PTR;  /* reset configuration pointer */
    }
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    else
    {
        /* do nothing */
    }
    Pwm_SetModuleStateBeforeExitApi(checkResult, (uint8)PWM_DEINIT_SERVICE_ID);
#endif 
}
#endif

#if (STD_ON == PWM_SET_DUTY_CYCLE_API)
/*!
* @brief         Used to change pwm signal's duty cycle.
*
* @param[in]     ChannelNumber      -pwm channel id
* @param[in]     DutyCycle          -pwm channel target duty cycle value
* @param[out]    None
* @param[in,out] None
*
* @retval        None
*/
FUNC(void, PWM_CODE) Pwm_SetDutyCycle(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber, VAR(uint16, AUTOMATIC) DutyCycle)
{
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    if((Std_ReturnType)E_OK == Pwm_CheckChIdAndSuitableForApi(ChannelNumber, (uint8)PWM_SETDUTYCYCLE_SERVICE_ID))
    {
        if((Std_ReturnType)E_OK == Pwm_CheckSetDutyCyclePara(DutyCycle, (uint8)PWM_SETDUTYCYCLE_SERVICE_ID))
        {
#endif
            Pwm_Tmr_SetDutyCycle(ChannelNumber, DutyCycle, (&s_pwmCfgPtr->pwmIpCfg)->pTmrIpCfgPtr);
#if (STD_ON == PWM_DEV_ERROR_DETECT)
        }
        else
        {
            /* do nothing */
        }
    }
    else
    {
        /* do nothing */
    }
#endif
}
#endif

#if (STD_ON == PWM_SET_PERIOD_AND_DUTY_API)
/*!
* @brief         Used to change pwm signal's period and duty cycle.
*
* @param[in]     ChannelNumber      -pwm channel id
* @param[in]     Period             -pwm channel target period value
* @param[in]     DutyCycle          -pwm channel target duty cycle value
* @param[out]    None
* @param[in,out] None
*
* @retval        None
*/
FUNC(void, PWM_CODE) Pwm_SetPeriodAndDuty(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber,
                                          VAR(Pwm_PeriodType, AUTOMATIC) Period,
                                          VAR(uint16, AUTOMATIC) DutyCycle)
{
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    if((Std_ReturnType)E_OK == Pwm_CheckChIdAndSuitableForApi(ChannelNumber, (uint8)PWM_SETPERIODANDDUTY_SERVICE_ID))
    {
        if((Std_ReturnType)E_OK == Pwm_CheckSetPeriodAndDutyPara((*s_pwmCfgPtr->pChClassNotifyPtr)[ChannelNumber].pwmChClass,
                                                                 Period, DutyCycle, (uint8)PWM_SETPERIODANDDUTY_SERVICE_ID))
        {
#endif
            Pwm_Tmr_SetPeriodAndDuty(ChannelNumber, Period, DutyCycle, (&s_pwmCfgPtr->pwmIpCfg)->pTmrIpCfgPtr);
#if (STD_ON == PWM_DEV_ERROR_DETECT)
        }
        else
        {
            /* do nothing */
        }
    }
    else
    {
        /* do nothing */
    }
#endif
}
#endif

#if (STD_ON == PWM_SET_OUTPUT_TO_IDLE_API)
/*!
* @brief         Used to set pwm channel output to idle.
*
* @param[in]     ChannelNumber      -pwm channel id
* @param[out]    None
* @param[in,out] None
*
* @retval        None
*/
FUNC(void, PWM_CODE) Pwm_SetOutputToIdle(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber)
{
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    if((Std_ReturnType)E_OK == Pwm_CheckChIdAndSuitableForApi(ChannelNumber, (uint8)PWM_SETOUTPUTTOIDLE_SERVICE_ID))
#endif
    {
        Pwm_Tmr_SetOutputToIdle(ChannelNumber, (&s_pwmCfgPtr->pwmIpCfg)->pTmrIpCfgPtr);
    }
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    else
    {
        /* do nothing */
    }
#endif
}
#endif

#if (STD_ON == PWM_GET_OUTPUT_STATE_API)
/*!
* @brief         Used to get pwm channel output state.
*
* @param[in]     ChannelNumber      -pwm channel id
* @param[out]    None
* @param[in,out] None
*
* @retval        Pwm_OutputStateType:PWM_LOW/PWM_HIGH
*/
FUNC(Pwm_OutputStateType, PWM_CODE) Pwm_GetOutputState(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber)
{
    VAR(Pwm_OutputStateType, AUTOMATIC) ret = (Pwm_OutputStateType)PWM_LOW;

#if (STD_ON == PWM_DEV_ERROR_DETECT)
    if((Std_ReturnType)E_OK == Pwm_CheckChIdAndSuitableForApi(ChannelNumber, (uint8)PWM_GETOUTPUTSTATE_SERVICE_ID))
#endif
    {
        ret = Pwm_Tmr_GetOutputState(ChannelNumber, (&s_pwmCfgPtr->pwmIpCfg)->pTmrIpCfgPtr);
    }
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    else
    {
        /* do nothing */
    }
#endif

    return (Pwm_OutputStateType)ret;
}
#endif

#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
/*!
* @brief         Used to disable pwm channel notification.
*
* @param[in]     ChannelNumber      -pwm channel id
* @param[out]    None
* @param[in,out] None
*
* @retval        None
*/
FUNC(void, PWM_CODE) Pwm_DisableNotification(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber)
{
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    if((Std_ReturnType)E_OK == Pwm_CheckChIdAndSuitableForApi(ChannelNumber, (uint8)PWM_DISABLENOTIFICATION_SERVICE_ID))
#endif
    {
        Pwm_Tmr_DisableNotification(ChannelNumber, (&s_pwmCfgPtr->pwmIpCfg)->pTmrIpCfgPtr);
    }
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    else
    {
        /* do nothing */
    }
#endif
}

/*!
* @brief         Used to enable pwm channel notification.
*
* @param[in]     ChannelNumber      -pwm channel id
* @param[in]     Notification       -edge class to trig notification
* @param[out]    None
* @param[in,out] None
*
* @retval        None
*/
FUNC(void, PWM_CODE) Pwm_EnableNotification(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber,
                                            VAR(Pwm_EdgeNotificationType, AUTOMATIC) Notification)
{
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    if((Std_ReturnType)E_NOT_OK == Pwm_CheckChIdAndSuitableForApi(ChannelNumber, (uint8)PWM_ENABLENOTIFICATION_SERVICE_ID))
    {
        /* nothing to do */
    }
    else if((Std_ReturnType)E_NOT_OK == Pwm_CheckPwmChNotifyCfg(ChannelNumber))
    {
        /* nothing to do */
    }
    else
#endif
    {
        Pwm_Tmr_EnableNotification(ChannelNumber, Notification, (&s_pwmCfgPtr->pwmIpCfg)->pTmrIpCfgPtr);
    }
}
#endif

#if (STD_ON == PWM_LOW_POWER_STATE_ENABLE)
/*!
* @brief         Used to get current pwm module power state.
*
* @param[in]     None
* @param[out]    CurrentPowerState      -save current power state
* @param[out]    Result                 -API execute result
* @param[in,out] None
*
* @retval        Std_ReturnType:E_OK/E_NOT_OK
*/
FUNC(Std_ReturnType, PWM_CODE) Pwm_GetCurrentPowerState
                              (P2VAR(Pwm_PowerStateType, AUTOMATIC, PWM_APPL_DATA) CurrentPowerState,
                               P2VAR(Pwm_PowerStateRequestResultType, AUTOMATIC, PWM_APPL_DATA) Result)
{
    VAR(Std_ReturnType, AUTOMATIC)  returnValue = (Std_ReturnType)E_OK;

    if((NULL_PTR == Result) || (NULL_PTR == CurrentPowerState))
    {
        returnValue = (Std_ReturnType)E_NOT_OK;
#if (STD_ON == PWM_DEV_ERROR_DETECT)
        (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX, 
                              (uint8)PWM_GETCURRENTPOWERSTATE_SERVICE_ID, (uint8)PWM_E_PARAM_POINTER);
#endif
    }
    else
    {
#if (STD_ON == PWM_DEV_ERROR_DETECT)
        returnValue = Pwm_CheckPwmModuleState((uint8)PWM_GETCURRENTPOWERSTATE_SERVICE_ID);

        if((Std_ReturnType)E_OK == returnValue)
#endif
        {
            *CurrentPowerState = s_pwmCurrentPowerState;
            *Result = PWM_SERVICE_ACCEPTED;
        }
#if (STD_ON == PWM_DEV_ERROR_DETECT)
        else
        {
            *Result = PWM_NOT_INIT;
        }

        Pwm_SetModuleStateBeforeExitApi(returnValue, (uint8)PWM_GETCURRENTPOWERSTATE_SERVICE_ID);
#endif
    }

    return returnValue;
}

/*!
* @brief         Used to get target pwm module power state.
*
* @param[in]     None  
* @param[out]    TargetPowerState       -save target power state
* @param[out]    Result                 -API execute result
* @param[in,out] None
*
* @retval        Std_ReturnType:E_OK/E_NOT_OK
*/
FUNC(Std_ReturnType, PWM_CODE) Pwm_GetTargetPowerState
                               (P2VAR(Pwm_PowerStateType, AUTOMATIC, PWM_APPL_DATA) TargetPowerState,
                                P2VAR(Pwm_PowerStateRequestResultType, AUTOMATIC, PWM_APPL_DATA) Result)
{
    VAR(Std_ReturnType, AUTOMATIC)  returnValue = (Std_ReturnType)E_OK;
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    VAR(Std_ReturnType, AUTOMATIC)  checkResult = (Std_ReturnType)E_OK;
#endif

    if((NULL_PTR == Result) || (NULL_PTR == TargetPowerState))
    {
        returnValue = (Std_ReturnType)E_NOT_OK;
#if (STD_ON == PWM_DEV_ERROR_DETECT)
        (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX, 
                              (uint8)PWM_GETTARGETPOWERSTATE_SERVICE_ID, (uint8)PWM_E_PARAM_POINTER);
#endif
    }
    else
    {
#if (STD_ON == PWM_DEV_ERROR_DETECT)
        checkResult = Pwm_CheckPwmModuleState((uint8)PWM_GETTARGETPOWERSTATE_SERVICE_ID);

        if((Std_ReturnType)E_OK == checkResult)
#endif
        {
            *TargetPowerState = s_pwmTargetPowerState;
            *Result = PWM_SERVICE_ACCEPTED;
        }
#if (STD_ON == PWM_DEV_ERROR_DETECT)
        else
        {
            returnValue = (Std_ReturnType)E_NOT_OK;
            *Result = PWM_NOT_INIT;
        }

        Pwm_SetModuleStateBeforeExitApi(checkResult, (uint8)PWM_GETTARGETPOWERSTATE_SERVICE_ID);
#endif
    }

    return returnValue;
}

/*!
* @brief         Used for pwm module power state change.
*
* @param[in]     PowerState     -target state of pwm module power 
* @param[out]    Result         -result of execute this API
* @param[in,out] None
*
* @retval        Std_ReturnType:E_OK/E_NOT_OK
*/
FUNC(Std_ReturnType, PWM_CODE) Pwm_PreparePowerState(VAR(Pwm_PowerStateType, AUTOMATIC) PowerState,
                               P2VAR(Pwm_PowerStateRequestResultType, AUTOMATIC, PWM_APPL_DATA) Result)
{
    VAR(Std_ReturnType, AUTOMATIC)  returnValue = (Std_ReturnType)E_OK;

    if(NULL_PTR == Result)
    {
        returnValue = (Std_ReturnType)E_NOT_OK;
#if (STD_ON == PWM_DEV_ERROR_DETECT)
        (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX,
                              (uint8)PWM_PREPAREPOWERSTATE_SERVICE_ID, (uint8)PWM_E_PARAM_POINTER);
#endif
    }
    else
    {
#if (STD_ON == PWM_DEV_ERROR_DETECT)
        returnValue = Pwm_CheckPwmModuleState((uint8)PWM_PREPAREPOWERSTATE_SERVICE_ID);

        if((Std_ReturnType)E_OK == returnValue)
#endif
        {
            if(s_pwmCurrentPowerState != PowerState)
            {
                if((PWM_LOW_POWER != PowerState) && (PWM_FULL_POWER != PowerState))
                {
                    *Result = PWM_POWER_STATE_NOT_SUPP;
                    returnValue = (Std_ReturnType)E_NOT_OK;
#if (STD_ON == PWM_DEV_ERROR_DETECT)
                    (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX, 
                                          (uint8)PWM_PREPAREPOWERSTATE_SERVICE_ID, (uint8)PWM_E_POWER_STATE_NOT_SUPPORTED);
#endif
                }
                else
                {
                    *Result = PWM_SERVICE_ACCEPTED;
                    s_pwmTargetPowerState = PowerState;
                }
            }
            else
            {
                *Result = PWM_SEQUENCE_ERROR;
                returnValue = (Std_ReturnType)E_NOT_OK;
            }
        }
#if (STD_ON == PWM_DEV_ERROR_DETECT)
        else
        {
            *Result = PWM_NOT_INIT;
        }

        Pwm_SetModuleStateBeforeExitApi(returnValue, (uint8)PWM_PREPAREPOWERSTATE_SERVICE_ID);
#endif
    }

    return returnValue;
}

/*!
* @brief         Used to set pwm module power state.
*
* @param[in]     None
* @param[out]    Result      -API execute result
* @param[in,out] None
*
* @retval        Std_ReturnType:E_OK/E_NOT_OK
*/
FUNC(Std_ReturnType, PWM_CODE) Pwm_SetPowerState
                               (P2VAR(Pwm_PowerStateRequestResultType, AUTOMATIC, PWM_APPL_DATA) Result)
{
    VAR(Std_ReturnType, AUTOMATIC)  returnValue = (Std_ReturnType)E_OK;

    if(NULL_PTR == Result)
    {
        returnValue = (Std_ReturnType)E_NOT_OK;
#if (STD_ON == PWM_DEV_ERROR_DETECT)
        (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX,
                              (uint8)PWM_SETPOWERSTATE_SERVICE_ID, (uint8)PWM_E_PARAM_POINTER);
#endif
    }
    else
    {
#if (STD_ON == PWM_DEV_ERROR_DETECT)
        returnValue = Pwm_CheckPwmModuleState((uint8)PWM_SETPOWERSTATE_SERVICE_ID);

        if((Std_ReturnType)E_OK == returnValue)
#endif
        {
            if(s_pwmCurrentPowerState == s_pwmTargetPowerState)
            {
                *Result = PWM_SERVICE_ACCEPTED;
            }
            else
            {
                if(PWM_NODEFINE_POWER == s_pwmTargetPowerState)
                {
#if (STD_ON == PWM_DEV_ERROR_DETECT)
                    (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX, 
                                          (uint8)PWM_SETPOWERSTATE_SERVICE_ID, (uint8)PWM_E_PERIPHERAL_NOT_PREPARED);
#endif
                    *Result = PWM_SEQUENCE_ERROR;
                    returnValue = (Std_ReturnType)E_NOT_OK;
                }
                else
                {
                    if((PWM_LOW_POWER != s_pwmTargetPowerState) && (PWM_FULL_POWER != s_pwmTargetPowerState))
                    {
#if (STD_ON == PWM_DEV_ERROR_DETECT)
                        (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX,
                                              (uint8)PWM_SETPOWERSTATE_SERVICE_ID, (uint8)PWM_E_POWER_STATE_NOT_SUPPORTED);
#endif
                        *Result = PWM_POWER_STATE_NOT_SUPP;
                        returnValue = (Std_ReturnType)E_NOT_OK;
                    }
                    else
                    {
                        returnValue = Pwm_CheckChIdleState(&s_pwmCfgPtr->pwmIpCfg);
                        if((Std_ReturnType)E_OK == returnValue)
                        {
                            if (NULL_PTR != (&s_pwmCfgPtr->pwmIpCfg)->pTmrIpCfgPtr)
                            {
                                Pwm_Tmr_SetPowerState((&s_pwmCfgPtr->pwmIpCfg)->pTmrIpCfgPtr, s_pwmTargetPowerState);
                            }
                            else
                            {
                                /* do nothing */
                            }

                            *Result = PWM_SERVICE_ACCEPTED;
                            s_pwmCurrentPowerState = s_pwmTargetPowerState;
                            s_pwmTargetPowerState = PWM_NODEFINE_POWER;
                        }
                        else
                        {  
                            (void)Det_ReportRuntimeError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX,
                                                         (uint8)PWM_SETPOWERSTATE_SERVICE_ID, (uint8)PWM_E_NOT_DISENGAGED);
                            *Result = PWM_HW_FAILURE;
                        }
                    }
                }
            }
        }
#if (STD_ON == PWM_DEV_ERROR_DETECT)
        else
        {
            *Result = PWM_NOT_INIT;
        }

        Pwm_SetModuleStateBeforeExitApi(returnValue, (uint8)PWM_SETPOWERSTATE_SERVICE_ID);
#endif
    }

    return returnValue;
}

/*!
* @brief         AUTOSAR defined.
*
* @param[in]     None
* @param[out]    None
* @param[in,out] None
*
* @retval        None
*/
FUNC(void, PWM_CODE) Pwm_Main_PowerTransitionManager(void)
{
}
#endif

#if (STD_ON == PWM_GET_VERSION_INFO)
/*!
* @brief         Used to get pwm mcal version information.
*
* @param[in]     None
* @param[out]    None
* @param[in,out] versioninfo      -point to pwm mcal version information struct
*
* @retval        None
*/
FUNC(void, PWM_CODE) Pwm_GetVersionInfo(P2VAR(Std_VersionInfoType, AUTOMATIC, PWM_APPL_DATA) versioninfo)
{
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    if(NULL_PTR == versioninfo)
    {
        (void)Det_ReportError((uint16)PWM_H_MODULE_ID, (uint8)PWM_INDEX, 
                              (uint8)PWM_GETVERSIONINFO_SERVICE_ID, (uint8)PWM_E_PARAM_POINTER);
    }
    else
#endif
    {
        (versioninfo)->vendorID         = (uint16)PWM_H_VENDOR_ID;
        (versioninfo)->moduleID         = (uint16)PWM_H_MODULE_ID;
        (versioninfo)->sw_major_version = (uint8) PWM_H_SW_MAJOR_VERSION;
        (versioninfo)->sw_minor_version = (uint8) PWM_H_SW_MINOR_VERSION;
        (versioninfo)->sw_patch_version = (uint8) PWM_H_SW_PATCH_VERSION;
    }
}
#endif

#ifdef PWM_DUAL_CLOCK_MODE_SUPPORTED
#if (STD_ON == PWM_DUAL_CLOCK_MODE_SUPPORTED)
/*!
* @brief         Used to set pwm clock prescaler.
*
* @param[in]     ClkPscMode    -pwm clock prescaler parameter
* @param[out]    None
* @param[in,out] None
*
* @retval        None
*/
FUNC(void, PWM_CODE) Pwm_SetClkPrescaler(VAR(Pwm_ClockDivisionType, AUTOMATIC) ClkPscMode)
{
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    VAR(Std_ReturnType, AUTOMATIC) checkResult = Pwm_CheckPwmModuleState((uint8)PWM_SETCLKPRESCALER_SERVICE_ID);

    if((Std_ReturnType)E_OK == checkResult)
#endif
    {
        if (NULL_PTR != (&s_pwmCfgPtr->pwmIpCfg)->pTmrIpCfgPtr)
        {
            Pwm_Tmr_SetClkPrescaler(ClkPscMode, (&s_pwmCfgPtr->pwmIpCfg)->pTmrIpCfgPtr);
        }
        else
        {
            /* do nothing */
        }
    }
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    else
    {
        /* do nothing */
    }
    Pwm_SetModuleStateBeforeExitApi(checkResult, (uint8)PWM_SETCLKPRESCALER_SERVICE_ID);
#endif
}
#endif
#endif

#if (STD_ON == PWM_SET_OUTPUT_TO_ACTIVE)
/*!
* @brief         Used to set pwm channel output is active level.
*
* @param[in]     ChannelNumber    -channel id
* @param[out]    None
* @param[in,out] None
*
* @retval        None
*/
FUNC(void, PWM_CODE) Pwm_SetOutputToActive(VAR(uint8, AUTOMATIC) ChannelNumber)
{
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    if((Std_ReturnType)E_OK == Pwm_CheckChIdAndSuitableForApi(ChannelNumber, (uint8)PWM_SETOUTPUTTOACTIVE_SERVICE_ID))
#endif
    {
        Pwm_Tmr_SetOutputToActive(ChannelNumber, (&s_pwmCfgPtr->pwmIpCfg)->pTmrIpCfgPtr);
    }
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    else
    {
        /* do nothing */
    }
#endif
}
#endif

#if (STD_ON == PWM_SOFTWARE_RESET_COUNTER)
/*!
* @brief         Used to reset timer count.
*
* @param[in]     InstanceId      -instance id
* @param[out]    None
* @param[in,out] None
*
* @retval        None
*/
FUNC(void, PWM_CODE) Pwm_SoftwareResetCounter(VAR(uint8, AUTOMATIC) InstanceId)
{
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    VAR(Std_ReturnType, AUTOMATIC) checkResult = Pwm_CheckPwmModuleState((uint8)PWM_SOFTWARERESETCOUNTER_SERVICE_ID);

    if((Std_ReturnType)E_NOT_OK == checkResult)
    {
        Pwm_SetModuleStateBeforeExitApi(checkResult, (uint8)PWM_SOFTWARERESETCOUNTER_SERVICE_ID);
    }
    else if((Std_ReturnType)E_NOT_OK == Pwm_CheckPwmInstanceId((uint8)InstanceId, (uint8)PWM_SOFTWARERESETCOUNTER_SERVICE_ID))
    {
        Pwm_SetModuleStateBeforeExitApi(checkResult, (uint8)PWM_SOFTWARERESETCOUNTER_SERVICE_ID);
    }
    else
#endif
    {
        Pwm_Tmr_SoftwareResetCounter(InstanceId);

#if (STD_ON == PWM_DEV_ERROR_DETECT)
        Pwm_SetModuleStateBeforeExitApi(checkResult, (uint8)PWM_SOFTWARERESETCOUNTER_SERVICE_ID);
#endif
    }
}
#endif

#if (STD_ON == PWM_GET_CHANNEL_DUTYCYCLE)
/*!
* @brief         Used to get pwm channel signal dutycycle value.
*
* @param[in]     ChannelNumber      -pwm channel id
* @param[out]    None
* @param[in,out] None
*
* @retval        uint16 : dutyCycleValue
*/
FUNC(uint16, PWM_CODE) Pwm_GetChDutyCycleValue(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber)
{
    VAR(uint16, AUTOMATIC) dutyCycleValue = (uint16)0U;

#if (STD_ON == PWM_DEV_ERROR_DETECT)
    if((Std_ReturnType)E_OK == Pwm_CheckChIdAndSuitableForApi(ChannelNumber, (uint8)PWM_GETCHDUTYCYCLEVALUE_SERVICE_ID))
#endif
    {
        dutyCycleValue = Pwm_Tmr_GetChDutyCycleValue(ChannelNumber);
    }
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    else
    {
        /* do nothing */
    }
#endif

    return dutyCycleValue;
}
#endif

#if (STD_ON == PWM_TURN_ON_OFF_CHANNEL)
/*!
* @brief         Used to turn on/off pwm channel output.
*
* @param[in]     ChannelNumber    -pwm channel id
* @param[in]     operaFlag        -TRUE-turn on, FALSE-turn off
* @param[out]    None
* @param[in,out] None
*
* @retval        None
*/
FUNC(void, PWM_CODE) Pwm_TurnOnOffChannel(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber, VAR(boolean, AUTOMATIC) operaFlag)
{
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    if((Std_ReturnType)E_OK == Pwm_CheckChIdAndSuitableForApi(ChannelNumber, (uint8)PWM_TURNONOFFCHANNEL_SERVICE_ID))
#endif
    {
        Pwm_Tmr_TurnOnOffChannel(ChannelNumber, operaFlag, (&s_pwmCfgPtr->pwmIpCfg)->pTmrIpCfgPtr);
    }
#if (STD_ON == PWM_DEV_ERROR_DETECT)
    else
    {
        /* do nothing */
    }
#endif
}
#endif

#if (STD_ON == PWM_NOTIFICATION_SUPPORTED)
/*!
* @brief         Used to execute pwm channel notification function.
*
* @param[in]     ChannelNumber      -pwm channel id
* @param[out]    None
* @param[in,out] None
*
* @retval        None
*/
FUNC(void, PWM_CODE) Pwm_ExecuteNotificationFunction(VAR(Pwm_ChannelType, AUTOMATIC) ChannelNumber)
{
    VAR(uint8, AUTOMATIC) chHw = 0U;

    VAR(Pwm_ChNotifyType, AUTOMATIC) ptrFunc = NULL_PTR;

    if(NULL_PTR != s_pwmCfgPtr)
    {
        chHw = s_pwmCfgPtr->logicChMapToHwCh[ChannelNumber];

        ptrFunc = (*s_pwmCfgPtr->pChClassNotifyPtr)[chHw].pwmChNotifyPtr;

        if(NULL_PTR != ptrFunc)
        {
            ptrFunc();
        }
        else
        {
            /* do nothing */
        }
    }
    else
    {
        /* do nothing */
    }
}
#endif

#if (STD_ON == PWM_FAULT_CHECK_SUPPORTED) || (STD_ON == PWM_OVERFLOW_CHECK_SUPPORTED)
/*!
* @brief         Used to get IpCfg pointer.
*
* @param[in]     None
* @param[out]    None
* @param[in,out] None
*
* @retval        Pwm_IpCfgType
*/
FUNC(P2CONST(Pwm_IpCfgType, AUTOMATIC, PWM_APPL_CONST), PWM_CODE) Pwm_GetIpCfgPtr(void)
{
    P2CONST(Pwm_IpCfgType, AUTOMATIC, PWM_APPL_CONST) ipCfgPtr = NULL_PTR;

    if(NULL_PTR == s_pwmCfgPtr)
    {
        ipCfgPtr = NULL_PTR;
    }
    else
    {
        ipCfgPtr = &s_pwmCfgPtr->pwmIpCfg;
    }

    return ipCfgPtr;
}
#endif

/**@} end of group PWM_Fuctions */

#define PWM_STOP_SEC_CODE
#include "Pwm_MemMap.h"

#ifdef __cplusplus
}
#endif

/**@} end of group PWM_Driver */
/**@} end of group G32A10xx_StdPeriphDriver */
